Frage Dieser BackgroundWorker ist derzeit beschäftigt und kann nicht mehrere Aufgaben gleichzeitig ausführen


Ich erhalte diesen Fehler, wenn ich auf eine Schaltfläche klicke, die den Hintergrundarbeiter zweimal startet.

This BackgroundWorker is currently busy and cannot run multiple tasks concurrently

Wie kann ich das vermeiden?


43
2018-02-25 22:12


Ursprung


Antworten:


Ganz einfach: Starten Sie den BackgroundWorker nicht zweimal.

Sie können überprüfen, ob es bereits ausgeführt wird, indem Sie das verwenden IsBusy Eigenschaft, also ändere diesen Code einfach:

worker.RunWorkerAsync();

zu diesem:

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

Aktualisieren:

Wenn Sie mehrere Hintergrundaufgaben gleichzeitig starten müssen, können Sie einfach mehrere BackgroundWorker-Objekte erstellen


86
2018-02-25 22:14



Erstellen Sie ein neues BackgroundWorker-Objekt für jede Operation, die Sie ausführen möchten. I.e., anstatt:

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

Versuche dies:

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

51
2018-03-21 01:20



Ich würde in die Warteschlange der Aufgaben schauen, die getan werden müssen. Sie erhalten die folgenden Vorteile;

  • Sie müssen nicht mit den Problemen von Hintergrundaufgaben umgehen, die nicht gestartet werden können, weil etwas anderes bereits ausgeführt wird
  • Sie müssen sich keine Gedanken darüber machen, zu viele Threads zu verwenden, indem Sie für jede Aufgabe einen neuen Hintergrund erstellen.
  • Zuletzt die Warteschlange könnte Damit können Sie sicherstellen, dass die Hintergrundaufgaben in derselben Reihenfolge ausgeführt werden, in der sie erstellt / angefordert wurden.

Hier ist eine Beispielimplementierung: http://thevalerios.net/matt/2008/05/a-queued-backgroundworker. Ich bin nicht sicher, ob die Implementierung in threadsafe, und ich werde meine Antwort aktualisieren, sobald ich herausfinden, von meinem aktuellen Sperrproblem in einer Implementierung, mit der ich arbeite.


5
2017-08-26 11:07



Obwohl dies ursprünglich nicht vom OP gefordert wurde, kann dies auch aufgrund einer Race-Bedingung passieren (die mir jetzt passiert ist und nach einer Antwort gesucht hat), wenn Sie einen Hintergrund-Worker in einer Art Produzenten-Konsumenten-Muster verwenden.

Beispiel:

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

In diesem Fall gibt es eine Race Condition: Die erste Instanz instanziiert einen neuen Background Worker, die zweite Instanz erreicht die else if und startet den Hintergrund-Worker, bevor die erste Instanz den RunWorkerAsync des if Block, und wenn es tut, wirft es den Fehler.

Dies kann vermieden werden, indem dem gesamten if + if-sonst-Abschnitt eine Sperre hinzugefügt wird.


1
2018-04-24 14:02