あなたのために何かをするオブジェクトの架空の方法を考えてみましょう:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
どのようにBackgroundWorkerが完了するのを待つことができますか?
過去に人々は試みました:
while (_worker.IsBusy)
{
Sleep(100);
}
しかし、このデッドロック、理由はIsBusy
後になるまでクリアされないRunWorkerCompleted
イベントが処理され、アプリケーションがアイドル状態になるまでそのイベントが処理取得することはできません。ワーカーが完了するまで、アプリケーションはアイドル状態になりません。(さらに、それは忙しいループです-嫌です)。
他の人はそれを提案するkludgingに追加しました:
while (_worker.IsBusy)
{
Application.DoEvents();
}
これに関する問題は、Application.DoEvents()
現在キューにあるメッセージが処理され、再入可能性の問題が生じることです(.NETは再入可能ではありません)。
私は、コードがイベントを待つイベント同期オブジェクトを含むいくつかのソリューションを使用したいと思います-ワーカーのRunWorkerCompleted
イベントハンドラーが設定します。何かのようなもの:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
しかし、私はデッドロックに戻りました。アプリケーションがアイドル状態になるまでイベントハンドラーは実行できません。アプリケーションは、イベントを待機しているため、アイドル状態になりません。
では、BackgroundWorkerが完了するのをどのように待つことができますか?
Update Peopleはこの質問に混乱しているようです。彼らは私がBackgroundWorkerを次のように使用することを考えているようです:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
それはあるではないですもの、それはない私がやっている、それはありません、ここで求められているもの。その場合、バックグラウンドワーカーを使用しても意味がありません。