form - backgroundworker c# progressbar
Este BackgroundWorker está actualmente ocupado y no puede ejecutar múltiples tareas al mismo tiempo (4)
Obtengo este error si hago clic en un botón que inicia dos veces el backgroundworker.
This BackgroundWorker is currently busy and cannot run multiple tasks concurrently
¿Cómo puedo evitar esto?
Aunque no es el caso originalmente planteado por el OP, esto también puede ocurrir debido a una condición de carrera (me pasó ahora y busqué una respuesta) si está utilizando un trabajador de Background en algún tipo de patrón productor-consumidor.
Ejemplo:
if (BckgrndWrkr == null)
{
BckgrndWrkr = new BackgroundWorker();
BckgrndWrkr.DoWork += DoWorkMethod;
BckgrndWrkr.RunWorkerAsync();
}
else if (!BckgrndWrkr.IsBusy)
{
BckgrndWrkr.RunWorkerAsync();
}
En este caso hay una condición de carrera: la primera instancia instancia un nuevo trabajador en segundo plano, la segunda instancia llega al else if
e inicia el trabajador en segundo plano, antes de que la primera instancia llegue al RunWorkerAsync del bloque if
y, cuando lo hace, arroja el error.
Esto se puede evitar agregando un bloqueo a toda la sección if + if else.
Cree un nuevo objeto BackgroundWorker para cada operación que desee realizar. Es decir, en lugar de:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
for (int i; i < max; i++) {
worker.RunWorkerAsync(i);
}
Prueba esto:
for (int i; i < max; i++) {
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync(i);
}
Me gustaría analizar las tareas que deben hacerse. Obtienes las siguientes ventajas;
- No tiene que manejar los problemas de las tareas en segundo plano que no se pueden iniciar debido a algo más que ya se está ejecutando
- No tiene que preocuparse por utilizar demasiados subprocesos, creando un nuevo fondo para cada tarea.
- Por último, la cola podría permitirle asegurarse de que las tareas en segundo plano se ejecuten en el mismo orden en que fueron creadas / solicitadas.
Aquí hay una implementación de ejemplo: http://thevalerios.net/matt/2008/05/a-queued-backgroundworker . No estoy seguro de si la implementación está en encriptado, y actualizaré mi respuesta una vez que descubra mi problema de bloqueo actual en una implementación con la que estoy trabajando.
Simple: no inicie el BackgroundWorker dos veces.
Puede verificar si ya se está ejecutando utilizando la propiedad IsBusy
, así que simplemente cambie este código:
worker.RunWorkerAsync();
a esto:
if( !worker.IsBusy )
worker.RunWorkerAsync();
else
MessageBox.Show("Can''t run the worker twice!");
Actualizar:
Si realmente necesita iniciar varias tareas en segundo plano al mismo tiempo, simplemente puede crear varios objetos de BackgroundWorker