This BackgroundWorker is currently busy and cannot run multiple tasks concurrently

时间秒杀一切 提交于 2019-11-28 05:13:18

Simple: Don't start the BackgroundWorker twice.

You can check if it is already running by using the IsBusy property, so just change this code:

worker.RunWorkerAsync();

to this:

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

Update:

If you do actually need to launch multiple background tasks at the same time, you can simply create multiple BackgroundWorker objects

Create a new BackgroundWorker object for each operation that you want to perform. I.e., rather than:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
for (int i; i < max; i++) {
   worker.RunWorkerAsync(i);
}

Try this:

for (int i; i < max; i++) {
   BackgroundWorker worker = new BackgroundWorker();
   worker.DoWork += new DoWorkEventHandler(worker_DoWork);
   worker.RunWorkerAsync(i);
}

I would look into queue'ing the tasks that need to be done. You get the following advantages;

  • You do not have to handle the problems of background tasks not being able to start due to something else already running
  • You do not have to worry about using up too many threads, by creating a new background worked for each task.
  • Lastly the queue could allow you to ensure that the background tasks run in the same order as they where created/requested.

Here is an example implementation: http://thevalerios.net/matt/2008/05/a-queued-backgroundworker. I am not sure if the implementation in threadsafe, and I will update my answer once I figure out of my current locking problem in a implementation I am working with.

Although not the case originally asked by the OP, this can also happen due to a race condition (happened to me now, and looked for an answer) if you're using a Background worker in some sort of a producer-consumer pattern.

Example:

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

In this case there's a race condition: first instance instantiates a new background worker, 2nd instance reaches the else if and starts the background worker, before 1st instance reaches the RunWorkerAsync of the if block, and when it does it throws the error.

This can be avoided by adding a lock to the entire if + if else section.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!