2013-12-14 14 views
8

Jestem nieco zdezorientowany, jak sobie poradzić z wyjątkiem.Obsługa wyjątków pracowników tła

Mam wątek pracownika tła, który uruchamia jakiś długotrwały proces. Rozumiem, że jeśli wystąpi wyjątek w wątku pracującym w tle, kod nadal będzie kończył się na metodzie RunWorkerCompleted.

void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 

     if (e.Error != null) 
      throw e.Error; 

Jeśli jest to sprawa jest jakiś punkt w oddanie bloku try catch wokół bgWorker.RunWorkerAsync(); zadzwoń, nie zakładam?

Chcę ponownie rzucić wyjątek złapany w RunWorkerCompleted metoda, jak mogę to zrobić bez utraty śledzenia stosu - czy to, co mam powyżej poprawne? Czytałem, że podczas ponownego wyrzucania wyjątku powinieneś po prostu użyć "rzutu"?

Odpowiedz

13

Proponuję stworzyć jakiś konkretny wyjątek biznesowy, który opisuje działanie, które robisz w tle. I wyrzucić ten wyjątek z oryginalnym wyjątku jako wewnętrzny wyjątek:

private void bgWorker_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
     throw new BusinessSpecificException("Operation failed", e.Error); 
    // ... 
} 

Zatem oryginalny wyjątek z jego ślad stosu będzie dostępny, a będziesz miał wyjątek bardziej opisowe rzucony.

Uwaga - jeśli nie chcesz tworzyć nowej klasy wyjątku, możesz użyć istniejącego ApplicationException lub Exception. Ale to nie tak dobrze poinformowany i jeśli masz zamiar go złapać gdzieś, to nie będzie w stanie złapać tego szczególnego wyjątku tylko

2

If this is the case is there any point in putting a try catch block around the bgWorker.RunWorkerAsync(); call, I assume not?

Nie, nie może tego zrobić, ponieważ bgWorker.RunWorkerAsync(); jest to metoda (nie an event). f używasz debugera Visual Studio, debugger zostanie przerwany w punkcie obsługi zdarzenia DoWork, w którym został zgłoszony nieobsługiwany wyjątek. Więc można zrobić coś takiego

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      try 
      { 
       //put your break point here 
       // here you can capture your exception 
      } 
      catch (Exception ex) 
      { 
       // here catch your exception and decide what to do     
       throw; 
      } 



     } 
+0

więc w tym przypadku nie będę potrzebujesz wykonać jakąkolwiek obsługę błędów w mojej metodzie RunWorkerCompleted? A może lepszą praktyką jest radzenie sobie z błędami w metodzie RunWorkerCompleted? – mHelpMe

+0

jeśli zajmiesz się wyjątkiem w wątku roboczym, nie będziesz mógł go pobrać w RunWorkerCompleted i jeśli nie będziesz go obsługiwał w DoWork, twoja aplikacja może ulec awarii, jeśli zrobisz coś źle –

7

Spróbuj

void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 

     if (e.Error != null) 
      throw new Exception("My Custom Error Message", e.Error);