Frage

Ich frage mich, was der beste Weg, eine zu haben ist „wenn alle Stricke es nicht fangen“.

Ich meine, dich Umgang mit Ihnen so viele Ausnahmen wie möglich in Ihrer Anwendung, aber immer noch gibt es zwangsläufig Fehler sein, also muss ich etwas haben, das fängt alle unbehandelte Ausnahmen, so kann ich Informationen und Laden sammeln sie in einer Datenbank oder legt sie auf einem Web-Service.

Hat das AppDomain.CurrentDomain.UnhandledException Ereignis alles erfassen? Selbst wenn die Anwendung ist multithreaded?

Side Hinweis: Windows Vista macht native API-Funktionen, die für jede Anwendung ermöglichen erholen sich nach einem Absturz ... kann jetzt nicht denken Sie an den Namen ... aber ich möchte lieber nicht verwenden Sie es, so viele unserer Nutzer noch mit Windows XP.

War es hilfreich?

Lösung

Ich habe gerade mit AppDomain des UnhandledException Verhalten gespielt, (Dies ist die letzte Stufe der nicht behandelte Ausnahme bei registriert ist)

Ja, nach der Verarbeitung der Event-Handler Ihre Anwendung beendet wird und die fiesen „... Programm aufgehört zu arbeiten Dialog“ gezeigt.

:) Sie noch kann man erkennen, vermeiden.

Check out:

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. handhaben Sie das nicht behandelte für Application.ThreadException (WinForms) oder DispatcherUnhandledException (WPF) auf der höheren Ebene.

Andere Tipps

In ASP.NET, verwenden Sie die Application_Error Funktion in der Global.asax Datei.

In WinForms, verwenden Sie die MyApplication_UnhandledException in der ApplicationEvents Datei

sind Beiden Funktionen aufgerufen, wenn eine nicht behandelte Ausnahme in Ihrem Code auftritt. Sie können die Ausnahme anmelden und eine nette Nachricht aus diesen Funktionen für den Benutzer darstellen.

Für Winform-Anwendungen, zusätzlich zu AppDomain.CurrentDomain.UnhandledException Ich benutze auch Application.ThreadException und Application.SetUnhandledExceptionMode (w / UnhandledExceptionMode.CatchException). Diese Kombination scheint alles zu fangen.

Auf dem Haupt-Thread, haben Sie folgende Möglichkeiten:

Für andere Themen:

  • Sekundär Threads haben keine unhandled-Ausnahmen; verwenden SafeThread
  • Worker-Threads: (Timer, Threadpool) gibt es überhaupt kein Sicherheitsnetz

Beachten Sie, dass diese Ereignisse nicht behandeln Ausnahmen, sie nur sie an die Anwendung - oft, wenn es viel zu spät ist, etwas zu tun nützlich / sane über sie

Protokollierung Ausnahmen sind gut, aber Monitoring-Anwendungen sind besser; -)

Caveat. Ich bin der Autor des SafeThread Artikel

Für WinForms, vergessen Sie nicht, auch auf den aktuellen Thread nicht behandelte Ausnahmeereignis zu befestigen (vor allem, wenn Sie Multi-Threading verwenden).

Einige Links auf Best Practices hier und hier und hier (wahrscheinlich der beste Ausnahmebehandlung Artikel für .net)

Es gibt auch eine coole Sache namens ELMAH , die alle ASP.NET-Fehler protokolliert, dass tritt in einer Web-Anwendung. Ich weiß, Sie fragen, um eine Winform App Lösung, aber ich fühlte dies von Vorteil für jeden, könnte diese Art der Sache auf einer Web-App zu benötigen. Wir verwenden es, wo ich arbeite und es war in dem Debuggen sehr hilfreich (vor allem auf Produktionsservern!)

Hier einige Features, die es (zog sich direkt an der Seite) hat:

  
      
  • Protokollierung von fast allen unbehandelten Ausnahmen.
  •   
  • Eine Web-Seite aus der Ferne das gesamte Protokoll von umcodiert Ausnahmen anzuzeigen.
  •   
  • Eine Webseite aus der Ferne die vollständigen Details von einem protokollierten Ausnahme anzuzeigen.
  •   
  • In vielen Fällen können Sie den ursprünglichen gelben Schirm des Todes überprüfen, die   ASP.NET erzeugt für einen bestimmten   Ausnahme, auch mit Custom Modus   ausgeschaltet.
  •   
  • Eine E-Mail-Benachrichtigung über jeden Fehler zu der Zeit sie auftritt.
  •   
  • Ein RSS-Feed der letzten 15 Fehler aus dem Protokoll.
  •   
  • Eine Reihe von Sicherungsspeicher-Implementierungen für das Protokoll, einschließlich   In-Memory, Microsoft SQL Server und   mehrere von der Gemeinschaft beigetragen hat.
  •   

Sie können die meisten Ausnahmen in diesem Handler auch in Multi-Thread-Anwendungen überwachen, aber .NET (mit 2.0 Start) werden Sie Ausnahmen aufheben unhandled nicht zulassen, wenn Sie den 1.1-Kompatibilitätsmodus zu aktivieren. Wenn das der AppDomain passiert wird, egal heruntergefahren, was. Das Beste, was Sie tun können, ist die App in einem anderen AppDomain zu starten, so dass Sie diese Ausnahme behandeln kann und eine neue AppDomain erstellen die App neu zu starten.

Ich bin mit dem folgenden Ansatz, der funktioniert und verringert die Menge an Code (aber ich bin nicht sicher, ob es ein besserer Weg ist oder was die Gefahren den sie sein könnten. Wann immer du anrufst: Ich quess die quys minuse gibt genug wäre höflich ihre Handlungen zu klären; )

try 
{
    CallTheCodeThatMightThrowException()
 }
catch (Exception ex)
{
    System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace ();
    Utils.ErrorHandler.Trap ( ref objUser, st, ex );
} //eof catch

Und hier ist der Fehlerbehandler Code: Nur um Klar-: objUser - ist das Objekt, die appusers Modellierung (Sie Informationen, wie zB Domain-Namen könnten, Abteilung, Region usw. zur Protokollierung ILog Logger - ist das Objekt Protokollierung - z derjenige, der die Protokollierung Aktivitäten durchführen Stacktrace st - das Objekt Stacktrace geben Sie info Debuggen für Ihre App

using System;
using log4net; //or another logging platform

namespace GenApp.Utils
{
  public class ErrorHandler
  {
    public static void Trap ( Bo.User objUser, ILog logger, System.Diagnostics.StackTrace st, Exception ex )
    {
      if (ex is NullReferenceException)
      { 
      //do stuff for this ex type
      } //eof if

      if (ex is System.InvalidOperationException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.IndexOutOfRangeException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.Data.SqlClient.SqlException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.FormatException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is Exception)
      {
        //do stuff for this ex type
      } //eof catch

    } //eof method 

  }//eof class 
} //eof namesp

In einer manged GUI-Anwendung, die standardmäßig Ausnahmen, die in dem GUI-Thread stammen, werden behandelt, indem alles, was mit dem Application.ThreadException zugeordnet ist.

Ausnahmen, die in den anderen Threads stammen, werden durch AppDomain.CurrentDomain.UnhandledException behandelt.

Wenn Sie Ihr GUI-Thread Ausnahmen wollen wie Ihr-non-GUI diejenigen arbeiten, so dass sie von AppDomain.CurrentDomain.UnhandledException behandelt bekommen, können Sie dies tun:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);

Ein Vorteil der GUI-Thread Ausnahmen zu fangen Thread ist, dass Sie die Verwendung der Optionen zu lassen, die App weiter geben kann. Um sicherzustellen, dass keine Konfigurationsdateien Standardverhalten überschreiben, können Sie anrufen:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

Sie sind immer noch anfällig für Ausnahmen von schlecht benommen nativer DLLs. Wenn eine native DLL einen eigenen Handler Win32 SetUnhandledExceptionFilter installiert wird angenommen, den Zeiger auf den vorherigen Filter zu speichern und sie nennen. Wenn es nicht so tut, Handler wird nicht‘aufgerufen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top