[解決済み] BackgroundWorkerがキャンセルされるのを待つには?
質問
以下のような 仮定 メソッドを考えてみましょう。
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
イベントが処理されるまでクリアされず、そのイベントはアプリケーションがアイドル状態になるまで処理されないのです。Worker が終了するまで、アプリケーションはアイドル状態になりません。(さらに、それはビジー ループです。うんざりします。)
他の人は、それをクルーディングすることを提案しました。
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);
それは ではない それ、それは ではない 私がやっていることであり、それは ではなく ではありません。もしそうなら、バックグラウンド ワーカーを使用する意味はないでしょう。
どのように解決するのですか?
もし私があなたの要求を正しく理解していれば、次のようなことができるでしょう(コードはテストされていませんが、一般的なアイデアを示しています)。
private BackgroundWorker worker = new BackgroundWorker();
private AutoResetEvent _resetEvent = new AutoResetEvent(false);
public Form1()
{
InitializeComponent();
worker.DoWork += worker_DoWork;
}
public void Cancel()
{
worker.CancelAsync();
_resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
while(!e.Cancel)
{
// do something
}
_resetEvent.Set(); // signal that worker is done
}
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
[解決済み] enumを列挙するには
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] DateTime型の誕生日から年齢を計算するにはどうしたらいいですか?
-
[解決済み] Microsoft Officeをインストールせずに、C#でExcel(.XLSおよび.XLSX)ファイルを作成するにはどうすればよいですか?
-
[解決済み] wait()とsleep()の違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015