0

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 が発生します)

4

2 に答える 2

0

すべてのタスクが完了したら、別のイベントを発生させます。タスクを処理するためのロジックを、AllUrlsScannedイベントを受信したときに呼び出される別の関数に移動しました。

于 2009-02-06T13:00:01.780 に答える