10

ich mit den folgenden Komponenten gerade arbeitete:Backgroundausnahmebehandlung

  • eine Bibliothek (die eine Ausnahme auslöst)
  • eine Test-Konsole meiner Protokollierung
  • die Enterprise Library Ausnahmebehandlung Applikationsbausteine ​​zu testen
  • die Enterprise Library Logging-Applikationsbausteine ​​

ich Aufrufen der Bibliothek Methode unter Verwendung von ein Hintergrundarbeiter. Die Bibliothek löst die Ausnahme aus, aber der RunWorkerCompleted-Handler wird nie aufgerufen.

Die einzige Möglichkeit, die Ausnahme zu fangen, besteht darin, meinen DoWork-Handler-Code mit einem try/catch-Block zu umgeben.

Hat die RunWorkerCompletedEventArgs.Error-Eigenschaft missverstanden? Nicht um Ausnahmen zu bekommen, die vom BackgroundWorker abgefangen wurden?

codesample:

static BackgroundWorker w = new BackgroundWorker(); 

w.DoWork += new DoWorkEventHandler(w_DoWork); 
w.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(w_RunWorkerCompleted); 
w.RunWorkerAsync(); 



static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyClass m = new MyClass(); 
    w.result = m.Compute(); 
} 

static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     HandleException(e.Error); 
    } 

    /* result related code */ 

} 


static void HandleException(Exception e) 
{ 
    ExceptionPolicy.HandleException(e, "MyPolicy"); 
} 

Das obige Beispiel führt zu einer Beendigung meiner Konsolenanwendung. Die vs2010-Ausgabe schreibt absolut nichts (nur Standardausgabe).

Also, wo ist das Problem?

// Bearbeiten: Dieser Ausschnitt dient zum Abfangen der Ausnahme der Bibliothek.

static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     MyClass m = new MyClass(); 
     w.result = m.Compute(); 
    }catch(Exception e){ } 

} 
+1

Haben Sie etwas im Hauptthread, das verhindert, dass es endet? So etwas wie eine Weile (wahr)? – dcarneiro

+0

Sind Sie 100% sicher, dass RunWorkerCompleted nie aufgerufen wird? Hier ist eine SO-Frage, die beweist, dass dies funktionieren sollte ... http: //stackoverflow.com/questions/1044460/unhandled-exceptions-in-backgroundworker –

+1

Kannst du nicht debuggen und sehen, was passiert? Was gibt HandleException() zurück? – Reniuz

Antwort

7

Das ist das richtige Muster für BackgroundWorker.

Ich vermute, das Problem ist, dass Ihre Main Methode beendet wird, bevor das BW abgeschlossen hat.

RunWorkerAsync wird sofort zurück und wenn Sie nicht warten in Main, dann wird Ihr Prozess enden, vielleicht noch bevor das BW gestartet wurde, geschweige denn abgeschlossen.

Versuchen Sie, eine Console.ReadLine am Ende Ihrer Main Methode hinzuzufügen.


Aus Interesse:

BW verhält sich in einer Konsolenanwendung und einer Windows-Anwendung. Wenn Sie eine WinForms- oder WPF-App verwenden, wird ein abgeleiteter SynchronizationContext in Ihrem UI-Thread angezeigt, und BW wird RunWorkerCompleted zurück zum UI-Thread marshalieren und dort ausführen. Das ist einer der Hauptvorteile von BW.

In einer Konsolenanwendung wird der standardmäßige SynchronizationContext verwendet und dieser marshallt RunWorkerCompleted auf einen Threadpool-Thread. Dies bedeutet, dass Sie den Thread Main blockieren können und der abgeschlossene Handler weiterhin ausgeführt wird.

+0

Vielen Dank :) – csteinmueller

+0

Ich habe eine Konsolen-App genommen, weil es der schnellste Weg ist, eine Bibliothek zu testen. Ich brauche viel mehr Zeit, um meine Ergebnisse in einer WPF-Anwendung zu präsentieren. – csteinmueller

+7

@MartinJames Ich verbringe einen erheblichen Teil meiner Zeit mit dem Schreiben von Konsolen-Apps, die auf Servern geplant und ausgeführt werden. Ein UI wäre in solchen Situationen weder hilfreich noch durchführbar. Es ist auch einfacher, einfache Tests in einer Konsolen-App durchzuführen. weniger Aufwand, nur um etwas Einfaches zu tun und die Ergebnisse zu sehen. – Servy