2010-11-26 6 views
22

J'utilise l'événement suivant pour intercepter des exceptions non gérées dans le thread d'interface utilisateur principal.Attraper une exception non gérée sur des threads distincts

Application.ThreadException 

Malheureusement, il ne capture pas ces erreurs non gérées dans des threads séparés. Je suis conscient de

AppDomain.CurrentDomain.UnhandledException 

Cependant, cela semble fermer l'application lors du déclenchement, alors que l'ancien ne fonctionne pas.

Existe-t-il un moyen de gérer les exceptions non gérées sur des threads séparés, sans fermeture de l'application?

+6

Oui, assurez-vous que vos fils ne jettent pas exception non gérée. Comme le dit Eric Lippert: «la meilleure chose à faire est de supposer que chaque exception non gérée est soit une exception fatale, soit une exception non gérée, dans les deux cas, la bonne chose à faire est d'arrêter immédiatement le processus. http://blogs.msdn.com/b/ericlippert/archive/2010/11/23/asynchrony-in-c-5-part-eight-more-exceptions.aspx – Ani

+4

Vous avez oublié la meilleure partie de cet article: " Comme Ripley l'a dit, quand les choses tournent mal, vous devez enlever et attaquer le site entier de l'orbite, c'est la seule façon d'être sûr " –

Répondre

21

@Ani a déjà répondu à votre question. Bien que je ne suis pas d'accord que les exceptions non gérées dans les threads devraient mettre fin aux applications. L'utilisation de threads signifie généralement que vous avez une sorte d'application serveur. L'abattre pourrait entraîner beaucoup d'utilisateurs en colère.

J'ai écrit un petit morceau au sujet de la gestion des exceptions appropriée: http://blog.gauffin.org/2010/11/do-not-catch-that-exception/

Vous devez toujours prendre des exceptions pour les discussions. J'utilise habituellement le schéma suivant:

void ThreadMethod(object state) 
    { 
     try 
     { 
      ActualWorkerMethod(); 
     } 
     catch (Exception err) 
     { 
      _logger.Error("Unhandled exception in thread.", err); 
     } 
    } 

    void ActualWorkerMethod() 
    { 
     // do something clever 
    } 

Il est beaucoup plus facile de trouver des méthodes de fil qui ne gère pas les exceptions correctement en déplaçant la logique dans une méthode séparée et juste garder le bloc try/catch dans la méthode de fil .

+0

Excellent, merci. –

+1

Et si l'exception non gérée sur un autre thread est déclenchée par une méthode asynchrone privée d'un composant tiers que vous utilisez, comment obtenez-vous un crochet autour de cela? – MC5

+0

Vous ne pouvez pas, sauf si la bibliothèque de tiers fournit un moyen. En ce qui concerne les méthodes async (Begin/End), vous devez utiliser catch. Vous pouvez cependant intercepter l'exception (mais pas récupérer l'application) en utilisant l'événement 'AppDomain.UnhandledException'. – jgauffin

1

Oui, vous devez saisir manuellement les exceptions sur les threads.

Cependant, ce code:

void ThreadMethod(object state) 
{ 
    try 
    { 
     ActualWorkerMethod(); 
    } 
    catch (Exception err) 
    { 
     _logger.Error("Unhandled exception in thread.", err); 
    } 
} 

void ActualWorkerMethod() 
{ 
    // do something clever 
} 

peut être simplifié à l'aide de cette PostSharp:

[LogExceptions] 
void ActualWorkerMethod() 
{ 
    // do something clever 
} 
Questions connexes