Ceci est lié à un Question précédente . Qu'est-ce que j'essaie de comprendre maintenant, c'est comment se fait que les exceptions de fil de l'interface utilisateur peuvent être empêchées de mettre fin à l'application tandis que les exceptions non internes ne peuvent pas être. p>
pour référence, voir Cet exemple . P>
Plus important encore , ce que j'aimerais pouvoir faire dans ce cas est "silencieusement" résilier le processus - sans afficher la boîte de dialogue Windows qui demande si j'aimerais envoyer un rapport d'erreur ou non. P>
Ceci est mon AppDomain AnnuldedexceptionHandler: P>
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { // Maybe do some logging here if allowed } catch { } // then just terminate the application Application.Exit(); }
3 Réponses :
Ce n'est pas que toute exception Appdomain met fin à la demande, c'est que les exceptions non gérées (de toutes sortes) déchireront l'appdomain et termineront l'application. P>
Le problème ici est que vous pouvez gérer explicitement les exceptions de fil de l'interface utilisateur, à un niveau assez élevé. Toutefois, lorsque vous avez une exception non gérée dans un fil d'arrière-plan, il n'ya aucun moyen de manipuler facilement le même niveau, il a donc tendance à se propager et à extraire l'application. Application.threadException vous permet d'au moins savoir que c'est ce qui a provoqué l'erreur et le loger si nécessairement. P>
Les exceptions non gérées dans le fil de l'interface utilisateur provoqueront la même chose. P>
@Reed: "Les exceptions non gérées dans le fil de l'interface utilisateur provoqueront la même chose." - ce n'est pas vrai. Veuillez créer une application de test et essayez-la pour vous-même.
Techniquement, j'aurais dû dire "exceptions non manquées sur le fil principal". Les formulaires Windows ajoute son propre comportement de manipulation d'exception sur le fil de l'interface utilisateur (car il fonctionne entièrement sur le fil de l'interface utilisateur) qui change le comportement du fil principal. Faites une demande de console et essayez cela, et vous verrez que cela n'a pas d'importance sur les choses sur le thread sur - ils vont tous abattre l'application.
Ensuite, je devrais reformuler ma question: comment le fil de l'interface utilisateur accomplit-il que c'est un comportement général de manipulation d'exception? Est-ce quelque chose que je pouvais reproduire comme comportement pour un fil non-UI?
@Miky D: Vous devrez attraper des exceptions sur chaque fil. Gardez à l'esprit les threads qui pourraient être créés dans les coulisses sans démarrer manuellement un fil vous-même.
Eh bien, @max et @reed, clairement toutes les fonctions d'interface utilisateur contiennent des gestionnaires d'exception en eux-mêmes et pourtant les exceptions sont capturées par le gestionnaire de capture-tout requéron.threadException. Quelle est la "prise" (jeu de mots) ??
Cela a-t-il de l'aide du tout?
amélioration Comportement de exception non géré dans .NET 2.0 p>
En outre, ce code semble "mourir tranquillement". Cherchez-vous autre chose? P>
using System; namespace UnhandledException { class Program { static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; throw new NotImplementedException(); } static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception exception = (Exception)e.ExceptionObject; System.Console.WriteLine("exception=[" + exception.ToString() + "]"); Environment.Exit(-1); } } }
Oui, ça fait ... Je venais de finir de lire le poste et des commentaires lorsque vous avez posté cela. +1 Cependant ..
Oui, environemnemt.exit semble faire le tour! Je laisserai les questions ouvertes pendant un peu plus longtemps pour voir si quelqu'un peut donner un aperçu de la manière dont le fil de l'interface utilisateur accomplit l'exception. Sinon, vous aurez mon vote pour la réponse acceptée!
Application.threadException n'est qu'une autre variante d'un "gestionnaire d'exception non manquée". Il existe de nombreuses variantes (application de console contre Winforms vs. Webforms contre WCF, etc.). Je ne suis pas sûr de comprendre votre question. En général, je mettez en œuvre tout ce qui est applicable.
Quelque chose à garder à l'esprit: Enviroment.exit met fin à l'ensemble du processus, de sorte que la demande d'application vit dans une appdomaine côte à côte avec d'autres AppDomains tous tomberont ensemble ..
Après avoir fait des recherches supplémentaires sur Google, j'ai trouvé cette explication très intéressante donnée au même problème que celui décrit par Jeff Atwood sur son blog . P>
salut tout, Désolé pour la confusion. Ce comportement est en réalité la conception, bien que la conception puisse être un peu compliquée parfois. P>
La première chose à comprendre est que l'événement non gourmandesception n'est pas une exception non gérée "Handler". S'inscrire à l'événement, contrairement à ce que dit la documentation :-(, ne cause pas de manipuler des exceptions non gérées. strong> (depuis lors, ils ne seraient pas non faibles, mais je vais arrêter avec le raisonnement circulaire Déjà ...)
L'événement de NoSHLEDException vous informe simplement qu'une exception est devenue non heurtée forte>, au cas où vous voudriez essayer de sauvegarder l'état avant votre matricule de fil ou d'application. FWIW, j'ai déposé un bug pour obtenir les documents fixés. P> Juste pour compliquer les choses, en V1.0 et 1.1, une exception non gérée ne signifie pas toujours que votre demande mourrait. Si l'exception non heurtée s'est produite sur autre chose que le fil principal ou un fil qui a commencé sa vie dans un code non géré, le CLR a mangé l'exception et a permis à votre application de continuer. C'était généralement le mal, car ce qui se produirait souvent était, par exemple, que les threads Threadpool mourraient silencieusement, un par un, jusqu'à ce que votre application ne fasse pas de travail. Déterminer la cause de ce type d'échec était presque impossible. C'est pourquoi Jeff a pensé qu'il a fonctionné avant ... il a toujours vu des accidents sur des fils non principaux. P>
in v2.0, une exception non gérée sur tout thread prendra l'application. Nous avons constaté que cela est extrêmement plus facile de déboguer des accidents que de déboguer pendus ou du problème silencieux d'arrêt de travail décrit ci-dessus. P>
BTW, sur ma machine 1.1 L'exemple de MSDN a la production attendue; C'est juste que la deuxième ligne n'apparaît qu'après avoir joint un débogueur (ou non). En V2, nous avons renvoyé des choses autour de sorte que l'événement non gourmé avant que le débogueur attache, ce qui semble être ce que la plupart des gens attendent. P>
Jonathan Keljo Exception CLR PM Jonathan Keljo le 18 février 2005 10:02 P> blockQuote>
Cependant, je suis toujours intéressé par la manière dont le fil de l'interface utilisateur accomplit l'astuce de vous permettre d'avoir un gestionnaire de capture pour toutes les exceptions de fil de l'interface utilisateur. P>
Encore plus, Je suis très intéressé par un moyen de désactiver la boîte de dialogue de débogage de .NET JIT pour mon application uniquement forte> (sans
Désactivé pour l'ensemble de la machine, comme on le voit ) p>