Laden...

Bei zwei BackgroundWorkern wird RunWorkerCompeted nur einmal ausgelöst

Erstellt von Wax vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.837 Views
Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren
Bei zwei BackgroundWorkern wird RunWorkerCompeted nur einmal ausgelöst

Hallo zusammen,

ich beiß gleich in die Tastatur! 😃

Also.... Ich habe in meiner Anwendung zur Zeit 2 Objekte, die jeweils einen Backgroundworker instanzieren. Also 2 Objekte mit separaten Backgroundworkern!

Nun starten diese 2 Instanzen ihre Backgroundworker schnell hintereinander (also quasi liegen da nur ein paar einfache Zuweisungen zwischen den beiden Zeilen, welche den Backgroundworker starten). Das Resultat lautet, dass nur ein Backgroundworker das RunWorkerCompleted-Event feuert, der andere nicht.

Sobald ich aber die Evil-Anweisung


 System.Windows.Forms.Application.DoEvents()

nutze, läuft alles wie gewünscht. Also es werden dann brav beide RunworkerCompleted-Event´s gefeuert.

Was kann das sein? Ich will DoEvents nicht verwenden!!!

Mfg
wax

5.742 Beiträge seit 2007
vor 12 Jahren

Hallo Wax,

ein kleines Repro wäre da nicht schlecht.

Bist du sicher, dass beide Instanzen ihren eigenen BGW verwenden?

G
538 Beiträge seit 2008
vor 12 Jahren

Falls du das "wird nicht aufgerufen" mit dem Debugger festgestellt haben solltest, schau mal was passiert, wenn du ihn weiterlaufen lässt.

Denn Application.DoEvents sorgt ja nur dafür, dass dein aktueller Vorgang unterbrochen wird und anstehende Events verarbeitet werden.
Das heißt also, dein Event ist eingereiht und wartet, bis es dran ist.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren

Hi,

@winSharp93: Ja, jede Instanz hat ihren eigenen BGW.

@Grumbler85: Es passiert immer, wenn ich eben DoEvents() nicht aufrufe. Also ob im Debug oder wenn ich es einfach so laufen lasse. Das kann ich gut nachvollziehen, da im RunWorkerCompleted-EventHandler Dinge gemacht werden, die mein GUI verändern. Von daher sehe ich sofort, welcher BGW sich zurück meldet und welcher nicht.

Das komische an der ganzen Sache ist ja, dass beide DoWork-Eventhandler korrekt bis zum Schluss abgearbeitet werden. Nur leider feuert nur ein BGW das Completed-Event. 😦

MfG
wax

G
538 Beiträge seit 2008
vor 12 Jahren

Feuert denn immer der gleiche?
Wenn ja halte genau den mal mit Thread.Sleep() oder so an um zu sehen, was dann passiert ...

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren

Ja, es feuert immer der gleiche. Ein Sleep bringt keine Veränderung.

MfG
wax

5.742 Beiträge seit 2007
vor 12 Jahren

Poste doch bitte mal noch etwas mehr Code.

G
538 Beiträge seit 2008
vor 12 Jahren

Wäre es möglich, dass du schlicht das Event nicht abbonniert hast?

//edit: ne Quatsch.. du hast ja gesagt DoEvents() macht, dass es läuft ...

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren

Ok, also der Aufruf des BackgroundWorkers ist hier jetzt nicht zu sehen. Aber es passiert halt nichts ausser:


backGroundWorker.RunAsync();

Die beiden Events sind auch abbonniert!

Hier die EventHandler:


private void DataBackgroundWorker_DoWork(System.Object sender, System.ComponentModel.DoWorkEventArgs e)
{
    if ((this.DataBackGroundWorker.CancellationPending)) {
        e.Cancel = true;
    } 
    else {
        
        IData tempData = remoteProxy.LoadData(EType);
        if ((tempData != null)) {
            e.Result = tempData;
	}   

    }

}

private void DataBackgroundWorker_RunWorkerCompleted(System.Object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    this.DataObject = e.Result;

    // AdminDataLoaded ist ein Event !
    if (AdminDataLoaded != null) {
        AdminDataLoaded(this, EventArgs.Empty);
    }

}

Mfg
wax

G
538 Beiträge seit 2008
vor 12 Jahren

.. läuft der zweite BW denn richtig, wenn du den ersten ganz weglässt?

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Wax,

in einer Windows Forms Anwendung führt ein BGW alle seine Events in dem Thread aus, der ihn erzeugt hat. Der BGW geht davon aus, dass dies der bzw. ein GUI-Thread ist. Mit anderen Worten, in dem Thread, der den BGW startet, muss Application.Run laufen. Wenn nicht, werden die Events nicht oder nicht richtig verarbeitet.

herbivore

Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren

Hallo herbivore,

das ist sichergestellt. Das Objekt, dass den BackgroundWorker enthält und auch startet, ist ein UserControl und dieses wurde auf jeden Fall im GUI-Thread erstellt.

MfG
wax

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Wax,

wenn DoEvents hilft, dann spricht das aber deutlich dafür, dass Application.Run doch nicht bzw. nicht in dem richtigen Thread läuft oder aus anderem Grund blockiert ist, z.B. weil der erste Completed-EventHandler endlos läuft. Siehe [FAQ] Warum blockiert mein GUI?.

herbivore

Wax Themenstarter:in
731 Beiträge seit 2006
vor 12 Jahren

Guten Morgen,

das Problem hat sich in Luft aufgelöst, nachdem ich bemerken musste, dass der 2. BGW im Thread des 1. BGW gestartet wird. 😮

Somit war der erste Thread wohl in der Regel eher "fertig" und dem 2. BGW wurde der Boden unter den Füßen weggerissen. Also so stelle ich es mir jetzt vor...

Vielen Dank für die reichlichen Beiträge!

MfG
wax

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Wax,

Also so stelle ich es mir jetzt vor...

nein, es ist so, wie ich sagte. Der Event wurde nicht ausgelöst, weil in dem Ziel-Thread kein Application.Run lief. Und die Ursache dafür hast du gerade geliefert, weil nämlich der Ziel-Thread eben fälschlich der erste BackgroundWorker war und nicht der GUI-Thread.

herbivore