あなたのために何かをするオブジェクトの架空のメソッドを考えてみましょう:
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
他の人は、それを次のように提案しました:
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 が終了するのをどのように待つことができるでしょうか?
更新 人々はこの質問に混乱しているようです。彼らは、私が BackgroundWorker を次のように使用すると考えているようです。
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
それはそうではありません、それは私がやっていることではありません、そしてそれはここで尋ねられていることではありません. その場合、バックグラウンド ワーカーを使用しても意味がありません。