10

Je travaille avec les composants suivants:BackgroundWorker gestion des exceptions

  • une bibliothèque (qui jette une exception)
  • une console de test pour tester mon exploitation forestière
  • les blocs d'application de gestion des exceptions bibliothèque d'entreprise
  • les blocs d'application de journalisation de la bibliothèque de l'entreprise

J'invoque la méthode de la bibliothèque à l'aide un arrière-plan. La bibliothèque lève l'exception, mais le gestionnaire RunWorkerCompleted n'est jamais appelé. La seule façon d'attraper l'exception est d'entourer mon code de gestionnaire DoWork avec un bloc try/catch.

Avez-vous mal compris la propriété RunWorkerCompletedEventArgs.Error? N'est-ce pas pour obtenir des exceptions qui ont été interceptées par BackgroundWorker?

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"); 
} 

L'exemple ci-dessus conduit à une résiliation de mon application console. La sortie de vs2010 n'écrit absolument rien (seulement la sortie par défaut).

Alors où est le problème? // Éditer: cet extrait fonctionne pour intercepter l'exception de la bibliothèque.

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

} 
+1

Avez-vous quelque chose sur le fil principal qui l'empêche de se terminer? Quelque chose comme un moment (vrai)? – dcarneiro

+0

Êtes-vous sûr à 100% que le RunWorkerCompleted n'est jamais appelé? Voici une question SO qui prouve que cela devrait fonctionner ... http: //stackoverflow.com/questions/1044460/unhandled-exceptions-in-backgroundworker –

+1

vous ne pouvez pas déboguer et voir ce qui se passe? ce que HandleException() renvoie? – Reniuz

Répondre

7

C'est le modèle correct pour BackgroundWorker.

Je suppose que le problème est que votre méthode Main se termine avant la fin du BW.

RunWorkerAsync retournera immédiatement et si vous n'attendez pas dans Main, alors votre processus se terminera, peut-être même avant que le BW ait commencé, peu importe terminé. Essayez d'ajouter un code Console.ReadLine à la fin de votre méthode Main.


Sur intérêt:

BW comporte différemment dans une application console et une application de Windows. Si vous utilisez une application WinForms ou WPF, il y aura un SynchronizationContext dérivé sur votre thread d'interface utilisateur et BW va ramener le RunWorkerCompleted au thread de l'interface utilisateur et l'exécuter là. C'est l'un des principaux avantages de BW.

Dans une application de console, le paramètre SynchronizationContext par défaut est utilisé, ce qui place RunWorkerCompleted sur un thread de thread. Cela signifie que vous pouvez bloquer le thread Main et le gestionnaire terminé sera toujours exécuté.

+0

Merci beaucoup :) – csteinmueller

+0

J'ai pris une application Console, car c'est le moyen le plus rapide de tester une bibliothèque. Il me faut beaucoup plus de temps pour présenter mes résultats dans une application WPF. – csteinmueller

+7

@MartinJames Je passe une grande partie de mon temps à écrire des applications de console programmées et exécutées sur des serveurs. Une interface utilisateur ne serait ni utile ni faisable pour de telles situations. Il est également plus facile de faire des tests simples dans une application de console; moins frais généraux impliqués juste pour faire quelque chose de simple et voir les résultats. – Servy