Tout d’abord, quelques éléments d’arrière-plan: j’ai une application WinForms multithread qui effectue l’interopérabilité avec des DLL natives. Cette application se bloque parfois avec une exception non gérée et nous essayons de déterminer pourquoi cela se produit. Afin de le faciliter, je crée un gestionnaire d’exception global et je prévois de générer un fichier de vidage de processus à partir de celui-ci.
Nous arrivons maintenant à la question suivante: cette application possède à présent un gestionnaire pour Application.ThreadException
mais elle se bloque toujours avec une exception non gérée. Je pense à append un gestionnaire pour AppDomain.UnhandledException
également bien que je ne sois pas sûr que ça va aider. Existe-t-il une exception non gérée possible dans ce scénario qui ne sera pas interceptée par Application.ThreadException
?
Oui, Application.ThreadException peut uniquement intercepter les exceptions déclenchées dans le thread d’interface utilisateur. Dans le code exécuté en raison des notifications Windows. Ou, techniquement, les événements déclenchés par la boucle de message. La plupart des événements Winforms entrent dans cette catégorie.
Ce qu’il n’intercepte pas, ce sont les exceptions déclenchées sur n’importe quel thread n’appartenant pas à l’interface utilisateur, comme un thread de travail démarré avec Thread.Start (), ThreadPool.QueueUserWorkItem ou la méthode BeginInvoke () d’un délégué. Toute exception non gérée dans celles-ci mettra fin à l’application, AppDomain.UnhandledException est le dernier sursaut.
En descendant plus loin, les exceptions matérielles générées dans un thread non géré par du code natif qui n’a jamais effectué d’appel CLR géré ne peuvent être détectées avec aucun mécanisme CLR. AccessViolation (code d’exception 0xc0000005) est la cause de décès la plus courante. La seule façon de les intercepter consiste à utiliser l’API Windows, SetUnhandledExceptionFilter (). C’est difficile à obtenir.
Vous pouvez désactiver Application.ThreadException avec Application.SetUnhandledExceptionMode (). Ce qui est une bonne chose à faire, donner à l’utilisateur l’option Continuer n’a pas beaucoup de sens. Maintenant, toutes les exceptions dans les threads gérés se comportent de la même manière, utilisez AppDomain.UnhandledException pour les consigner.
Application.ThreadException
ne sera levé que pour les exceptions non gérées sur les threads de l’interface utilisateur WinForms (voir ici .) L’ajout d’un gestionnaire pour AppDomain.UnhandledException
pourrait être utile dans ce cas (avec quelques réserves cependant, comme décrit dans la section remarques ici .)
Je vous recommande vivement d’utiliser la génération de minidump du système d’exploitation au lieu de la vôtre. C’est pour plusieurs raisons:
ThreadException
ou UnhandledException
est démarré, la stack d’exceptions a déjà été déroulée. La génération d’un minidump à ce stade vous indiquera simplement le gestionnaire, pas la source de l’exception. Si votre application est sur le terrain, utilisez WER. Si vous effectuez des tests internes, utilisez ProcDump . Vous pouvez également simplement copier le fichier minidump pendant que la boîte de dialog Rapport d’erreurs est active.
PS Il existe certaines conditions exceptionnelles, notamment lorsque vous ThreadException
p / Invoke, où ni ThreadException
ni UnhandledException
ne fonctionneront.
PPS Si vous avez un scénario débogable, essayez d’activer les assistants de débogage gérés relatifs à p / Invoke.