7
votes

C # WINFFORMER STAFF STATIQUE VOID PRINCIPAL PAS APPORTER UNE EXCEPTION?

J'ai un winform écrit dans c # où je place un try-attraper bloc dans le programme.cs , dans la saisie du programme, la méthode statique (code> statique , juste au début de l'application, comme ceci: xxx

comme vous pouvez le voir, le Application est placé dans un try-attrayez bloc et dans le bloc , la seule chose que cela fait est de créer un fichier journal d'erreur.

maintenant, jusqu'à présent si bon. Mon application fonctionne bien et si je rencontre un crash, la dernière exception doit être capturée par le bloc track et stocké dans le fichier journal d'erreur.

Cependant, comme je cours mon programme pendant un moment, je reçois une exception non gérée ( null référence). Quelle surprise moi est que l'exception ne crée pas de fichier journal d'erreur.

maintenant, Ce message montre qu'il est éventuellement causé par threadexception ou guidageProcessancorruptedstatexceptions (Les deux réponses les plus avancées), mais mon cas montre une simple exception de référence null xxx

pourquoi serait-ce? < / p>


3 commentaires

Ce n'est pas la façon dont vous créez un gestionnaire d'exception global. Regardez à droite de cette page, dans la section «liée». La réponse acceptée Il vous dit quoi faire.


@jmcilhinney Vous voulez dire threadexception ?


Dans l'exemple, il y a // démarrez un nouveau thread, séparé des formulaires Windows, qui lancera une exception. Void privé Bouton2_Cliquez sur System.eventargs E) {Threadstarg NewThreadstart = Nouveau threadstart (NewTread_execute); NEWTHEAD = nouveau thread (NewToidsStart); NEWTTHEAD.START (); } qui gère délibérément une exception dans un nouveau fil. Mais cela peut créer une exception de référence null (comme mon cas) au lieu de threadexception (supposé être ce type - n'est-ce pas?)?


3 Réponses :


2
votes

threadexception n'est pas un type d'exception comme ( NullReferenceException ). C'est que:

Cet événement permet à votre application Windows Formulaires de gérer le contraire Des exceptions non confondues qui se produisent dans Windows forment des threads

Cela signifie qu'il gère des exceptions dans des threads autres que le fil principal.

Alors, vous devez vous abonner à: AppDomain.CurrentDomaine.UnhandledException Aussi pour gérer les exceptions dans votre thread principal (quel que soit le type de l'exception, par exemple NullReference , indexautofrange , etc ..).


0 commentaires

2
votes

OK, dans la fin I Mettre en place Application.setUnhandleXceptionMode (Non gredexceptionMode.ththrowException) Code> Comme examinée par Hans Passant pour vb.net code> in ce message . Ici, je mets mon propre code + journalisation des erreurs pour C # code>: xxx pré>

aussi, il semble que la source de confusion ici est qu'il y a réellement deux PROPAGÉES EXCEPTIONS CODE> se produisent: P>

La première a été une exception de l'application elle-même: p>

System.NullReferenceException: Object reference not set to an instance of an object.
   at T5ShortestTime.T5ShortestTimeForm.Dispose(Boolean disposing)
   at System.ComponentModel.Component.Finalize()


0 commentaires

5
votes

La dernière exception doit être capturée par le bloc Try-Catch

ça ne va pas arriver. Sauf dans un cas, lorsque vous exécutez votre programme avec un débogueur attaché. Donc, vous avez sûrement été balayée pour croire que cela fonctionnerait, tout le monde commence toujours à exécuter son programme avec F5 pendant un certain temps.

Application.Run () a une back-stop dans son code qui soulève des événements, essayez / Catch-EM-Tout ce qui augmente l'application.threadException lorsqu'un manipulateur d'événements jette une exception non gérée. Ce back-stop est vraiment, vraiment nécessaire, surtout sur la version x64 de Windows 7. Très mauvaises choses arrivent quand il n'y a pas de gestionnaire d'exception. Ce back-shirt n'est cependant pas en place lorsque vous courez avec le débogueur, qui rend les exceptions non difficiles trop difficiles à déboguer.

Ainsi, lorsque vous débogez, votre clause Catch sera exécutée. Faire des exceptions non difficiles trop difficiles à déboguer. Lorsque vous courez sans débogueur, votre clause de capture sera pas la course et votre programme se bloquera, tout comme vous l'avez décrit. Faire une exception non difficile trop difficile à déboguer.

Alors ne le fais pas de cette façon. Comment Application.Run () traite des exceptions non conventionnelles est configurée avec la méthode Application.setUnhandleXceptionMode (). Vous aimerez la version meilleure: xxx

avec ce code en place, vous pouvez déboguer des exceptions non heurtées sans aucun problème. Le test de débogueur.Sattachis garantit que le débogueur s'arrêtera toujours quand un gestionnaire d'événements tombe dessus. Sans débogueur, il désactive ensuite l'événement Application.ThreadException (il est assez inutile) et favorise l'écoute de toutes les exceptions . Y compris ceux soulevés dans des threads de travailleurs.

Vous devez donner une alerte à l'utilisateur afin que la fenêtre ne disparaisse donc pas sans aucune trace. J'allais recommander à MessageBox mais a remarqué que Ce bug est actuellement de retour sur Windows 10. soupir.


5 commentaires

Merci pour l'explication, cela devrait être la réponse. Une dernière question, vous dites que c'est particulièrement mauvais pour Windows 7 X64, j'utilise Windows 10 X64. Est-ce que cela fait de la différence? Dans votre message, vous avez déclaré: "Mise à jour vers Windows 8 ou ultérieure, elles ont résolu ce problème WOW64." - Je suppose que cela s'applique aussi à Windows 10, est-ce correct?


Win10 n'a pas ce problème, il est très spécifique à Win7.


D'accord merci. Ensuite, j'aurai la paix à l'esprit ...;) Je remarque également que le Dispose est toujours appelé après l'exception . Je implémente le setunhandleexceptionMode à thorteException , je l'ai testé avec un lancer un nouveau système.Exception () . Étonnamment, le programme génère des fichiers journaux d'erreur deux à la fois un . L'un est le system.exception , et l'autre est l'exception dans le Dispose - et celui dans le Dispose est produit plus tard . Pourquoi cela est-il ainsi? Est-ce que cela s'attendait à ce que le Dispose est toujours appelé après une exception fatale?


Il n'est pas très clair de ce qui dispose de la méthode dont vous parlez. Vraisemblablement, il s'agit en réalité de la surcharge (BOOL), elle est également appelée par le finaliseur. Vous devez choisir comment vous terminez votre programme, Environnement.exit () Nettoie toujours les finaliseurs en cours d'exécution, Environnement.Failfast () ne le fait pas. Disposer (Bool) ne doit pas faire quoi que ce soit de dangereux lorsque l'argument disposant est faux, vous ne voulez jamais planter le fil du finaliseur. Si cela n'aide pas, cliquez sur le bouton Posez une question.


L'explication dans le commentaire est utile. Il semble que la seconde exception est causée par l'environnement .exit . Quand je n'ai pas mis le environnement.exit mais remplacez par environnement.failfast (et oui, il s'agit du paramètre sans paramètre disposer < / Code> avait par le Winform ), le programme a fait pas produit deux journaux. Je m'attendrais également à ce que cela ferait la même chose si appdomain.currentdomaine.unhandledexception - = logexception; est utilisé. Merci encore! ;)