Web サイトをスクレイピングするためにアプリケーションにスレッドを実装しました。すべてのサイトがスクレイピングされたら、それらを処理したいと思います。
form は queueworker を作成します (これは 2 つのワーカーを作成し、タスクを処理します)。すべてのタスクが完了したら、フォームスレッドでそれらを処理したいと思います。この時点で、私はこれを
public void WaitForCompletion()
{
// Enqueue one null task per worker to make each exit.
StopWorkers();
//wait for the workers to finish
foreach (Thread worker in workers)
{
worker.Join();
}
}
タスクが実行された後、(queueworker から) 起動します。
public event EventHandler<ProgressEvent> UrlScanned;
if (UrlScanned != null)
{
UrlScanned(this, new ProgressEvent(task.Name, 1));
}
そして、そのイベントを次のようにキャッチします。
urlscanner.UrlScanned += new EventHandler<ProgressEvent>(UrlScanningProgress);
private void UrlScanningProgress(object sender, ProgressEvent args)
{
if (pbarurlScan.InvokeRequired)
{
//don't use invoke when Thread.Join() is used! Deadlock
Invoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args);
//BeginInvoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args)};
}
else
{
pbarurlScan.Value++;
}
}
問題は、formthread がブロックされ、Invoke を呼び出すとアプリケーション全体がデッドロック状態になることです。
デッドロックを発生させずにフォームスレッドを更新し、すぐに更新するにはどうすればよいですか (ワーカースレッドが完了すると begininvoke が発生します)