web-dev-qa-db-ja.com

このBackgroundWorkerは現在ビジーであり、複数のタスクを同時に実行できません

バックグラウンドワーカーを2回起動するボタンをクリックすると、このエラーが発生します。

This BackgroundWorker is currently busy and cannot run multiple tasks concurrently

どうすればこれを回避できますか?

49
Jade M

シンプル:BackgroundWorkerを2回起動しないでください。

IsBusyプロパティを使用して、既に実行されているかどうかを確認できます。次のコードを変更してください。

worker.RunWorkerAsync();

これに:

if( !worker.IsBusy )
    worker.RunWorkerAsync();
else
    MessageBox.Show("Can't run the worker twice!");

更新:

実際に複数のバックグラウンドタスクを同時に起動する必要がある場合は、単に複数のBackgroundWorkerオブジェクトを作成できます

92
Orion Edwards

実行する必要があるタスクのキューイングを検討します。次の利点があります。

  • 既に実行中の何かが原因でバックグラウンドタスクを開始できないという問題を処理する必要はありません。
  • 各タスクで機能する新しいバックグラウンドを作成することにより、スレッドを使いすぎることを心配する必要はありません。
  • 最後に、キューcouldを使用すると、バックグラウンドタスクが作成/要求されたときと同じ順序で実行されるようにできます。

以下に実装例を示します: http://thevalerios.net/matt/2008/05/a-queued-backgroundworker 。実装がスレッドセーフかどうかはわかりません。作業中の実装で現在のロックの問題がわかったら、答えを更新します。

7
Thies

OPが元々要求したケースではありませんが、何らかの生産者と消費者のパターンでバックグラウンドワーカーを使用している場合、これは競合状態(今私に起こり、答えを探している)によっても発生します。

例:

if (BckgrndWrkr == null)
{
    BckgrndWrkr = new BackgroundWorker(); 
    BckgrndWrkr.DoWork += DoWorkMethod;
    BckgrndWrkr.RunWorkerAsync();     
}
else if (!BckgrndWrkr.IsBusy)
{
    BckgrndWrkr.RunWorkerAsync();
}

この場合、競合状態があります。最初のインスタンスが新しいバックグラウンドワーカーをインスタンス化し、2番目のインスタンスがelse ifに到達し、1番目のインスタンスがifブロックのRunWorkerAsyncに到達する前に、エラーをスローしますか。

これは、if + if elseセクション全体にロックを追加することで回避できます。

1
David Refaeli