75 votes

.NET - Quelle est la meilleure façon d'implémenter un gestionnaire de "catch all exceptions" ?

Je me demande quelle est la meilleure façon d'avoir un "si tout le reste échoue, attrapez-le".

Je veux dire, vous gérez autant d'exceptions que possible dans votre application, mais il y aura toujours des bugs, donc j'ai besoin d'avoir quelque chose qui attrape toutes les exceptions non gérées afin que je puisse collecter des informations et les stocker dans une base de données ou les soumettre à un service web.

L'événement AppDomain.CurrentDomain.UnhandledException capture-t-il tout ? Même si l'application est multithreadée ?

Remarque : Windows Vista expose des fonctions natives de l'API qui permettent à toute application de se rétablir après un crash... je n'arrive pas à me souvenir du nom... mais je préférerais ne pas l'utiliser, car beaucoup de nos utilisateurs utilisent encore Windows XP.

33voto

modosansreves Points 1678

Je viens de jouer avec le comportement des UnhandledException de AppDomain, (c'est la dernière étape à laquelle l'exception non gérée est enregistrée)

Oui, après le traitement des gestionnaires d'événements, votre application sera interrompue et le désagréable "... programme stopped working dialog" sera affiché.

) Vous todavía peut éviter cela.

Vérifiez :

class Program
{
    void Run()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Console.WriteLine("Press enter to exit.");

        do
        {
            (new Thread(delegate()
            {
                throw new ArgumentException("ha-ha");
            })).Start();

        } while (Console.ReadLine().Trim().ToLowerInvariant() == "x");

        Console.WriteLine("last good-bye");
    }

    int r = 0;

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Interlocked.Increment(ref r);
        Console.WriteLine("handled. {0}", r);
        Console.WriteLine("Terminating " + e.IsTerminating.ToString());

        Thread.CurrentThread.IsBackground = true;
        Thread.CurrentThread.Name = "Dead thread";            

        while (true)
            Thread.Sleep(TimeSpan.FromHours(1));
        //Process.GetCurrentProcess().Kill();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("...");
        (new Program()).Run();
    }
}

P.S. Traitez les exceptions non gérées pour Application.ThreadException (WinForms) ou DispatcherUnhandledException (WPF) au niveau supérieur.

16voto

ine Points 10065

En ASP.NET, vous utilisez la fonction Application_Error dans le Global.asax fichier.

Dans WinForms, vous utilisez la fonction MyApplication_UnhandledException en el ApplicationEvents fichier

Ces deux fonctions sont appelées si une exception non gérée se produit dans votre code. Vous pouvez consigner l'exception et présenter un message agréable à l'utilisateur à partir de ces fonctions.

13voto

Bob Nadler Points 1959

Pour les applications Winform, outre AppDomain.CurrentDomain.UnhandledException, j'utilise aussi Application.ThreadException y Application.SetUnhandledExceptionMode (avec UnhandledExceptionMode.CatchException). Cette combinaison semble tout attraper.

6voto

Steven A. Lowe Points 40596

Sur le fil principal, vous disposez des options suivantes :

Pour les autres fils :

  • Les threads secondaires n'ont pas d'exceptions non gérées ; utilisez la fonction SafeThread
  • Fils de travail : (timer, threadpool) il n'y a pas de filet de sécurité du tout !

Gardez à l'esprit que ces événements ne poignée exceptions, ils ne font que rapport souvent lorsqu'il est bien trop tard pour faire quoi que ce soit d'utile ou de sensé à leur sujet.

Consigner les exceptions, c'est bien, mais surveiller les applications, c'est mieux ;-)

Avertissement : je suis l'auteur du SafeThread article.

4voto

Bogdan Maxim Points 2365

Pour WinForms, n'oubliez pas de vous attacher également à l'événement d'exception non gérée du Thread courant (surtout si vous utilisez le multi threading).

Quelques liens sur les meilleures pratiques aquí y aquí y ici (probablement le meilleur article sur la gestion des exceptions pour .net)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X