web-dev-qa-db-fra.com

Comment intercepter TOUTES les exceptions / plantages dans une application .NET

Duplicata possible:
. NET - Quelle est la meilleure façon d'implémenter un "gestionnaire de toutes les exceptions"

J'ai une application d'application console .NET qui plante 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/plantages possibles en installant divers 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/silencieux tous les cas d'erreur possibles?

39
DougN

Contrairement à ce que d'autres ont publié, il n'y a rien de mal à attraper toutes les exceptions. L'important est de les gérer tous de manière appropriée. Si vous avez un dépassement de pile ou une condition de mémoire insuffisante, l'application doit s'arrêter pour eux. Gardez également à l'esprit que les conditions de MOO peuvent empêcher votre gestionnaire d'exceptions de fonctionner correctement. Par exemple, si votre gestionnaire d'exceptions affiche une boîte de dialogue avec le message d'exception, si vous manquez de mémoire, il ne reste peut-être pas assez pour l'affichage de la boîte 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 autrement être manquées. Ensuite, lancez simplement un gestionnaire d'exceptions autour de votre boucle principale (en supposant une application winforms).

En outre, vous devez savoir que les exceptions OutOfMemoryExceptions ne sont pas toujours levées pour des conditions de mémoire insuffisante. Une condition de MOO peut déclencher toutes sortes d'exceptions, dans votre code ou dans le cadre, qui n'ont pas nécessairement quelque chose à voir avec le fait que la condition sous-jacente réelle est en mémoire. J'ai fréquemment vu InvalidOperationException ou ArgumentException lorsque la cause sous-jacente est en fait insuffisante en mémoire.

27
Pete Davis

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

43
Juanma

Cet article dans le projet de code de notre hôte Jeff Atwood est ce dont vous avez besoin. Comprend le code pour intercepter les exceptions non gérées et les meilleures pratiques pour afficher des informations sur le plantage à l'utilisateur.

11
Ricardo Amores

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

protected void Application_Error(Object sender, EventArgs e)

méthode

10
Drejc

Sachez que certaines exceptions sont dangereuses à attraper - ou pour la plupart inaccessibles,

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

Bien qu'attraper toutes les exceptions sans le plan pour les gérer correctement est sûrement une mauvaise pratique, je pense qu'une application devrait échouer d'une manière gracieuse. Un plantage ne devrait pas effrayer l'utilisateur à mort, et au moins il devrait afficher une description de l'erreur, des informations à signaler au support technique et, idéalement, un bouton pour fermer l'application et la redémarrer. Dans un monde idéal, l'application devrait pouvoir vider sur disque les données 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
4
Dario Solera

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

4
Mendelt

Vous pouvez également utiliser l'événement Application.ThreadException.

Une fois, je développais une application .NET fonctionnant dans une application basée sur COM; cet événement a été très utile, car AppDomain.CurrentDomain.UnhandledException ne fonctionnait pas dans ce cas.

3
petr k.

Je pense que vous ne devriez même pas attraper toutes les exceptions, mais mieux vaut les montrer à l'utilisateur. La raison en est que vous ne devez intercepter que les exceptions que vous pouvez réellement gérer. Si vous rencontrez une exception qui provoque l'arrêt du programme tout en le rattrapant, cela peut entraîner des problèmes beaucoup plus graves. Lisez également FAQ: Pourquoi FxCop met-il en garde contre les captures (exception)? .

1
hangy

N'oubliez pas 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 tester soigneusement.

1
Johnny Bravado

cela ne fait pas de mal d'utiliser les deux AppDomain.CurrentDomain.UnhandledException Application.ThreadException

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

0
Steven A. Lowe