0

通常、C# で backgroundWorker をキャンセルしたい場合は、次のようにします。

     while (backgroundWorker1.IsBusy)
     {
        backgroundWorker1.CancelAsync();
        autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT);
     }

1 つのアプリケーションには、多数の backgroundWorker があります。ヘルパー関数を使用して backgroundWorkers をキャンセルすることは有効ですか?

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are)
{
     while (bgw.IsBusy)
     {
        bgw.CancelAsync();
        are.WaitOne(BGW_CANCEL_TIMEOUT);
     }
}

私の懸念は、問題のオブジェクトを関数に渡す代わりにコピーが作成され、それによって関数を持つ目的が無効になることです。この関数を使用する主な目的は、コード スペースを削減し、アプリケーション コードをより読みやすく、保守しやすくすることです。

4

2 に答える 2

2

いいえ、これは大丈夫ではありません。BGWにRunWorkerCompletedイベントハンドラーがある場合、デッドロックが発生します。そのハンドラーは、メインスレッドがアイドル状態になり、メッセージループに再び入るまで実行できません。IsBusyプロパティは、そのイベントハンドラーが完了するまでTrueのままになります。

WaitOne呼び出しでタイムアウトが発生したため、少なくともプログラムが完全にハングすることはありません。しかし、WaitOne()が戻ったとき、BGWはまだ完了しておらず、RWCイベントハンドラーはまだ実行されていません。唯一の実用的な代替手段は、キャンセルが完了したときにRWCイベントハンドラーが必要な処理を実行することです。

于 2010-07-12T14:51:06.900 に答える
0

あなたのコードは間違っています。

を呼び出すと、BackgroundWorkerのフラグCancelAsyncが に設定されるだけです。イベント内のコードは定期的にこのフラグをチェックし、フラグが.CancellationPendingtrueDowWorktrue

何度も呼び出しCancelAsyncても意味がありません。実際にキャンセルされるまで UI スレッドをフリーズする必要はありません。

于 2010-07-12T14:44:43.770 に答える