Comment intercepter TOUTES les exceptions / blocages dans une application .NET [dupliquer]

StackOverflow https://stackoverflow.com/questions/82483

  •  01-07-2019
  •  | 
  •  

Question

  

Double possible:
   .NET - Quel & # 8217; s le meilleur moyen de mettre en œuvre un & # 8220; gestionnaire de capture de toutes les exceptions & # 8221;

J'ai une application d'application .NET qui se bloque et affiche un message à l'utilisateur. Tout mon code est dans un bloc try{<code>} catch(Exception e){<stuff>}, mais des erreurs sont toujours affichées.

Dans une application Win32, vous pouvez capturer toutes les exceptions / blocages possibles en installant différents gestionnaires d'exceptions:

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

Quel est l'équivalent dans le monde .NET pour que je puisse gérer / log / quiet tous les cas d'erreur possibles?

Était-ce utile?

La solution

Contrairement à ce que d’autres ont publié, il n’ya rien de mal à saisir toutes les exceptions. L'important est de les gérer tous de manière appropriée. Si vous avez un dépassement de capacité de la pile ou un manque de mémoire, l'application doit être fermée pour eux. En outre, gardez à l'esprit que les conditions de MOO peuvent empêcher votre gestionnaire d'exceptions de s'exécuter correctement. Par exemple, si votre gestionnaire d'exceptions affiche une boîte de dialogue avec le message d'exception, si la mémoire est insuffisante, il ne sera peut-être plus assez pour afficher les boîtes de dialogue. Il est préférable de l’enregistrer et de l’arrêter immédiatement.

Comme d'autres l'ont mentionné, il existe des événements UnhandledException et ThreadException que vous pouvez gérer pour collecter des exceptions qui pourraient sinon être manquées. Ensuite, lancez simplement un gestionnaire d'exceptions autour de votre boucle principale (en supposant qu'une application Winforms).

De plus, sachez que les exceptions OutOfMemoryExceptions ne sont pas toujours générées pour des conditions de mémoire insuffisante. Une condition de MOO peut déclencher toutes sortes d'exceptions, dans votre code ou dans la structure, qui n'ont nécessairement rien à voir avec le fait que la condition sous-jacente réelle manque de mémoire. J'ai souvent vu InvalidOperationException ou ArgumentException lorsque la cause sous-jacente manque de mémoire.

Autres conseils

Vous pouvez ajouter un gestionnaire d'événements à l'événement AppDomain.UnhandledException. Il sera appelé lorsqu'une exception est levée et non interceptée.

Cet article de codeproject de notre hôte Jeff Atwood est ce dont vous avez besoin. Inclut le code permettant de récupérer les exceptions non gérées et les meilleures pratiques permettant d'afficher des informations sur le blocage à l'utilisateur.

La classe Global.asax est votre dernière ligne de défense. Regardez:

protected void Application_Error(Object sender, EventArgs e)

méthode

Sachez que certaines exceptions sont dangereuses à capturer - ou presque impossibles à capturer,

  • OutOfMemoryException: tout ce que vous faites dans le gestionnaire des captures peut allouer de la mémoire (côté géré ou non géré du CLR) et ainsi déclencher un autre MOO
  • StackOverflowException: selon que le CLR le détecte suffisamment tôt ou non, vous pouvez être averti. Dans le pire des cas, cela tue simplement le processus.

Vous pouvez utiliser l'exception AppDomain.CurrentDomain.UnhandledException pour obtenir un événement.

Bien que capturer toutes les exceptions sans le plan pour les gérer correctement soit sûrement une mauvaise pratique, je pense qu'une application doit échouer de manière élégante. Un crash ne doit en aucun cas effrayer l'utilisateur, mais au moins afficher une description de l'erreur, des informations à signaler au support technique et, idéalement, un bouton permettant de fermer l'application et de la redémarrer. Dans un monde idéal, l’application devrait pouvoir dumper sur le disque les données de l’utilisateur, puis essayer de les récupérer (mais je vois que c’est trop demander).

Quoi qu'il en soit, j'utilise habituellement:

AppDomain.CurrentDomain.UnhandledException

Vous pouvez également utiliser Application.ThreadException Event.

Une fois, je développais une application .NET qui s'exécutait dans une application COM. cet événement était très utile, car AppDomain.CurrentDomain.UnhandledException ne fonctionnait pas dans ce cas.

Je pense que vous devriez plutôt ne même pas capturer toutes les exceptions, mais plutôt les laisser montrer à l'utilisateur. La raison en est que vous ne devez attraper que des exceptions que vous pouvez réellement gérer. Si vous rencontrez une Exception qui provoque l’arrêt du programme mais qui l’attrape tout de même, cela peut causer des problèmes beaucoup plus graves. Lisez également la FAQ: Pourquoi FxCop met-il en garde contre catch (exception)? .

Sachez que la capture de ces exceptions non gérées peut modifier les exigences de sécurité de votre application. Votre application peut cesser de fonctionner correctement dans certains contextes (lorsqu'elle est exécutée à partir d'un partage réseau, etc.). Assurez-vous de bien tester.

ça ne fait pas mal d'utiliser les deux     AppDomain.CurrentDomain.UnhandledException     Application.ThreadException

mais gardez à l'esprit que les exceptions sur les threads secondaires ne sont pas interceptées par ces gestionnaires; utilisez SafeThread pour les threads secondaires si nécessaire

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top