web-dev-qa-db-fra.com

Quelle est la différence entre Application.ThreadException et AppDomain.CurrentDomain.UnhandledException?

D'accord, c'est simple:

  • Quelle est la différence entre Application.ThreadException et
    AppDomain.CurrentDomain.UnhandledException?

  • Dois-je gérer les deux?

Merci!

102
JohnIdol

Application.ThreadException est spécifique aux formulaires Windows. Winforms exécute des gestionnaires d'événements en réponse aux messages qui lui sont envoyés par Windows. L'événement Click par exemple, je suis sûr que vous les connaissez. Si un tel gestionnaire d'événements lève une exception, il y a un arrêt dans la boucle de message Winforms qui intercepte cette exception.

Ce filet de sécurité déclenche l'événement Application.ThreadException . Si vous ne le remplacez pas, l'utilisateur obtiendra un ThreadExceptionDialog . Ce qui lui permet d'ignorer l'exception et de continuer à exécuter votre programme. Pas une bonne idée btw.

Vous pouvez désactiver ce comportement en appelant Application.SetUnhandledExceptionMode () dans la méthode Main () de Program.cs. Sans ce filet de sécurité en place, la chose habituelle se produit lorsqu'un thread meurt d'une exception non gérée: AppDomain.UnhandledException se déclenche et le programme se termine.

Fwiw: "ThreadException" était un très mauvais choix de nom. Cela n'a rien à voir avec les threads.

96
Hans Passant

Dans les applications qui utilisent Windows Forms, les exceptions non gérées dans le thread d'application principal provoquent le Application.ThreadException événement à déclencher. Si cet événement est géré, le comportement par défaut est que l'exception non gérée ne met pas fin à l'application, bien que l'application reste dans un état inconnu. Dans ce cas, l'événement UnhandledException n'est pas déclenché. Ce comportement peut être modifié à l'aide du fichier de configuration d'application ou à l'aide de Application.SetUnhandledExceptionMode méthode pour changer le mode en UnhandledExceptionMode.ThrowException avant que le gestionnaire d'événements ThreadException soit connecté. Cela s'applique uniquement au thread principal de l'application. L'événement UnhandledException est déclenché pour les exceptions non gérées levées dans d'autres threads.

À partir de Visual Studio 2005 , le cadre d'application Visual Basic fournit un autre événement pour les exceptions non gérées dans le thread d'application principal - WindowsFormsApplicationBase.UnhandledException. Cet événement a un objet arguments d'événement avec le même nom que l'objet arguments d'événement utilisé par AppDomain.UnhandledException, mais avec des propriétés différentes. En particulier, cet objet arguments d'événement possède une propriété ExitApplication qui permet à l'application de continuer à s'exécuter, en ignorant l'exception non gérée (et en laissant l'application dans un état inconnu). Dans ce cas, l'événement AppDomain.UnhandledException n'est pas déclenché.

Application.ThreadException peut être intercepté et l'application pourrait continuer (en général, ce n'est pas une bonne idée, mais pour l'application comme l'exécution périodique de certaines actions, c'est une bonne solution).

Pour intercepter les exceptions qui se produisent dans les threads non créés et détenus par Windows Forms, utilisez le AppDomain.UnhandledException. Il permet à l'application de consigner des informations sur l'exception avant que le gestionnaire par défaut du système ne signale l'exception à l'utilisateur et ne ferme l'application.
La gestion de cette exception n'empêche pas la fermeture de l'application.
. Après cela, le domaine d'application est déchargé et l'application se termine.

En commençant par . NET 4 , cet événement n'est pas déclenché pour les exceptions qui corrompent l'état du processus, telles que les débordements de pile ou les violations d'accès, sauf si le le gestionnaire d'événements est critique pour la sécurité et possède l'attribut HandleProcessCorruptedStateExceptionsAttribute.

Pour plus de détails, voir MSDN .

34
serhio

OK - je l'avais devant moi, ce morceau de code de msdn est assez explicite:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
18
JohnIdol

Eh bien, le problème est que ThreadException se produit en raison d'un problème avec votre thread, le Unhandled Exception est déclenché si votre code lève une exception qui n'est pas gérée.

La manière la plus simple de provoquer la seconde est de créer une application sans essayer ... attraper des blocs et lever une exception.

Maintenant, si vous avez besoin d'assurance, vous pouvez les gérer tous les deux, mais si vous capturez et gérez correctement votre exceptions, vous ne devriez pas avoir besoin du gestionnaire UnhandledException car c'est un peu comme un fourre-tout.

0
Joshua Cauble