Cette BackgroundWorker est actuellement occupé et ne peut pas exécuter plusieurs tâches simultanément

j'obtiens cette erreur si je clique sur un bouton qui démarre le backgroundworker deux fois.

This BackgroundWorker is currently busy and cannot run multiple tasks concurrently

Comment puis-je éviter cela?

45
demandé sur Alex Jolig 2009-02-26 01:12:11

4 réponses

Simple: Ne démarrez pas le BackgroundWorker deux fois.

vous pouvez vérifier si elle est déjà en cours d'exécution en utilisant le IsBusy propriété, il suffit donc de changer ce code:

worker.RunWorkerAsync();

à:

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

mise à Jour:

si vous avez réellement besoin de lancer plusieurs tâches d'arrière-plan en même temps, vous pouvez simplement créer plusieurs objets BackgroundWorker

87
répondu Orion Edwards 2012-12-04 20:18:46

Créer un nouvel objet BackgroundWorker pour chaque opération que vous souhaitez effectuer. I. e., au lieu de:

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

essaye ceci:

for (int i; i < max; i++) {
   BackgroundWorker worker = new BackgroundWorker();
   worker.DoWork += new DoWorkEventHandler(worker_DoWork);
   worker.RunWorkerAsync(i);
}
51
répondu Justin R. 2015-12-03 18:52:15

je me pencherais sur la mise en file d'attente des tâches à accomplir. Vous obtenez les avantages suivants;

  • vous n'avez pas à gérer les problèmes des tâches de fond ne pouvant pas démarrer en raison de quelque chose d'autre déjà en cours d'exécution
  • Vous n'avez pas à vous soucier d'utiliser trop de threads, par la création d'un nouveau fond travaillé pour chaque tâche.
  • Enfin la file d'attente vous permettent de vous assurer que les tâches de fond s'exécutent dans le même ordre comme ils ont été créés.

voici un exemple d'implémentation:http://thevalerios.net/matt/2008/05/a-queued-backgroundworker. Je ne suis pas sûr si l'implémentation dans threadsafe, et je vais mettre à jour ma réponse une fois que je me suis rendu compte de mon problème de verrouillage actuel dans une implémentation avec laquelle je travaille.

5
répondu Thies 2010-08-26 11:07:06

bien que ce ne soit pas le cas demandé à l'origine par L'OP, cela peut aussi se produire en raison d'une condition de race (cela m'est arrivé maintenant, et j'ai cherché une réponse) si vous utilisez un travailleur D'arrière-plan dans une sorte de modèle producteur-consommateur.

Exemple:

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

dans ce cas il y a une condition de race: la première instance instancie un nouveau travailleur d'arrière-plan, la seconde instance atteint le else if et démarre le background worker, avant que la 1ère instance atteigne le RunWorkerAsync de if bloc, et quand il le fait, il génère l'erreur.

ceci peut être évité en ajoutant une serrure à toute la section if + if else.

1
répondu David Refaeli 2018-04-24 14:02:45