Les exceptions C # ne sont capturées que lors du débogage?

Dupliquer possible:
Problème de gestion des exceptions en mode validation

Je soupçonne qu’il existe une explication parfaitement simple à cela, mais je n’arrive pas à le trouver.

Lorsque mon application WinForms C # 4.0 se charge dans le fichier Program.cs, la fonction Main () entière contient une instruction try / catch.

J’ai écrit un petit wrapper d’exception qui se comporte de manière assez similaire à la case “exception non capturée” .net, sauf qu’il fournit un peu plus d’informations, permet de sauvegarder l’arborescence des exceptions et de permettre à l’utilisateur d’envoyer l’erreur rapport directement à moi.

Maintenant, cela fonctionne bien lors du débogage (F5). Si je déclenche une exception n’importe où dans le programme qui se trouve dans le thread principal, s’il n’y a pas de tentative / interception, l’exception se déclenche jusqu’à Main () et affiche la fenêtre personnalisée.

(Toutes les autres exceptions que j’ai comptabilisées et sont traitées de manière appropriée).

Lorsque j’exécute le programme simplement en exécutant le fichier .exe, la boîte d’exception Vanilla .net s’affiche, pas celle que j’ai codée.

Y a-t-il une raison à laquelle cela pourrait arriver? Le plus étrange est qu’il se comporte de manière tout à fait différente lorsqu’il est exécuté en mode débogage. Je construis comme debug – pas de release.

Edit (22-mars-11):

J’ajoute simplement un petit addenda ici, au cas où certains d’entre vous ne trouveraient pas la réponse cachée dans les commentaires pour la réponse acceptée ci-dessous: Oubliez le fait que j’ai dit que je construisais en tant que débogage au lieu de publication. Cela n’a aucune pertinence – je l’ai simplement ajouté pour des informations supplémentaires. Ce qui est important, c’est que lorsque je débogue dans VS, les exceptions sont interceptées comme prévu, mais lorsqu’elles exécutent mon fichier EXE en dehors de VS, elles ne le sont pas.

Comme Cody l’a dit, Application.Run() a son propre gestionnaire d’exceptions, ce qui explique pourquoi ils n’atteignent jamais mon catch principal. Cependant, j’ai mentionné que je n’utilise même pas Application.Run() nulle part dans mon code … à la place de mon interface graphique est d’abord lancé avec Form.ShowDialog() .

J’ai fait quelques expériences et peux confirmer que Form.ShowDialog() se comporte de la même manière que Application.Run() en ce que les exceptions sont gérées dans la méthode elle-même.

C’est le comportement attendu.

La différence que vous voyez résulte de l’application en cours d’exécution avec le débogueur attaché. Lorsque vous le lancez à partir de Visual Studio, le débogueur est automatiquement attaché (à moins que vous ne choisissiez bien sûr de “Démarrer sans débogage”). Cela désactive le gestionnaire d’exceptions intégré, qui est chargé de vous montrer la boîte de dialog des exceptions .NET “vanilla”. Le lancer à partir de VS externe n’attache pas le débogueur, ce qui laisse la gestion des exceptions intégrée activée. (Notez que cela n’a rien à voir avec la compilation de votre programme en mode “Debug” par opposition au mode “Release”.)

Voir la réponse acceptée à cette question connexe pour plus d’informations. Je ne crois pas que la différence entre VB.NET et C # soit pertinente dans ce cas.

Comme le mentionne cette réponse, il existe un moyen de désactiver le gestionnaire d’exceptions intégré. Mais avant de choisir de le faire, je vous recommande de reconsidérer votre approche. Plutôt que d’envelopper toute votre méthode Main dans un bloc try-catch, ce qui me semble une odeur de code , vous pouvez envisager de gérer l’ événement intégré AppDomain.UnhandledException . Jeff Atwood a publié un article intéressant ici sur Code Project expliquant comment remplacer le traitement standard des exceptions .NET par une méthode plus conviviale. La solution qu’il propose est devenue d’autant plus élégante que les versions ultérieures du .NET FW ont amélioré la gestion de l’événement AppDomain.UnhandledException .