1

私は C# でアプリケーションを作成しており、Web ページから情報を取得するために複数の BackgroundWorker スレッドを作成しています。それらが BackgroundWorkers であるにもかかわらず、GUI フォームが応答しなくなりました。

デバッグ中、プログラムが応答しなくなったときに一時停止します。現在メイン スレッドにいることがわかり、Web ページのフェッチ メソッドで一時停止しています。ただし、このメソッドは新しいスレッドからのみ呼び出されるため、メイン スレッドに存在する理由がわかりません。

これは意味がありますか?Web リクエストがそれぞれのスレッドでのみ処理されるようにするにはどうすればよいですか?

編集:いくつかのコードと説明

大量の住所リストを処理しています。各スレッドは、1 つ以上のアドレスを処理します。作成するスレッドの数を選択できます (控えめにしています :))

//in “Controller” class
public void process()
{
for (int i = 1; i <= addressList.Count && i<= numthreads; i++) 
            {
                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += doWork;
                bw.RunWorkerAsync((object)i);
            }
}

public void doWork(object sender, DoWorkEventArgs e)
{
    //create an object that has the web fetching method, call it WorkObject
    //WorkObject keeps a reference to Controller. 
    //When it is done getting information, it will send it to Controller to print
    //generate a smaller list of addresses to work on, using e.Argument (should be 'i' from the above 'for' loop)
    WorkObject.workingMethod()
}

WorkObject が作成されると、「i」を使用してスレッド番号を認識します。これを使用して、情報を取得する Web アドレスのリストを取得します (メイン フォーム、コントローラー、および各 WorkObject によって共有されるアドレスのより大きなリストから - 各スレッドはアドレスのより小さなリストを処理します)。リストを反復処理するときに、「getWebInfo」メソッドを呼び出します。

//in “WorkObject” class
public static WebRequest request;

public void workingMethod()
{
    //iterate over the small list of addresses. For each one, 
        getWebInfo(address)
        //process the info a bit...then
        myController.print()

//note that this isn’t a simple “for” loop, it involves event handlers and threading 
//Timers to make sure one is done before going on to the next
}

public string getWebInfo (string address)
{
    request = WebRequest.Create(address);
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string content = reader.ReadToEnd();
                return content;
}
4

3 に答える 3

0

同様の状況で、独自のスレッド(BackgroundWorkerとThreadPoolを使用しない)を作成し、アクティブな接続の数を制限することで、より適切に制御できることがわかりました。IPアドレスをキューに書き込み、それぞれを選択してヘルパークラスに渡し、そこで新しいスレッドでDoSomethingメソッドを呼び出します。スレッドを起動するときにカウンターをインクリメントし、スレッドが完了するとカウンターをデクリメントしてスロットルします。ヘルパークラスのコールバックルーチンを使用して、UIスレッドに通知し、インターフェイスを更新するか、スレッドが終了したことを示すことができます。

UIを使用してスロットル制限を変更し、タスクマネージャーを監視してメモリとCPU使用率への影響を確認します。app.configにmaxconnection設定を追加して、より多くの同時接続を取得できます。

于 2009-11-24T23:20:53.747 に答える
0

BackgroundWorker の DoWork イベントですべての Web 作業を実行する必要がありますね。

クリップされたコードの一部は、何が起こっているのかを理解するのに役立つ場合があります。

于 2009-11-24T20:49:22.633 に答える
0

バックグラウンド ワーカーがハングを引き起こしている理由がわかりませんでしたが、同期 HTTP リクエストを使用する代わりに、次のガイドを使用して非同期に切り替えました。

http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/

すべてのハングアップをクリアしました。回答ありがとうございます。

于 2009-12-14T16:16:53.147 に答える