Wie gesamte Kette von Ausnahmen in Application.ThreadException Event-Handler zu bekommen?

StackOverflow https://stackoverflow.com/questions/61354

  •  09-06-2019
  •  | 
  •  

Frage

Ich arbeite nur auf Ausnahmebehandlung in einem .NET 2.0 app Festsetzung, und ich stolperte auf einig seltsames Problem mit Application.ThreadException .

Was ich will, ist in der Lage sein, alle Ausnahmen von den Ereignissen hinter GUI-Elementen zu fangen (z Button_Click, etc.). Ich möchte dann diese Ausnahmen auf ‚Verhängnis‘ filtern, zum Beispiel hält mit einigen Arten von Ausnahmen sollte die Anwendung ausgeführt und mit anderen sollte es verlassen.

In einer anderen .NET 2.0 app Ich habe gelernt, dass standardmäßig nur im Debug-Modus tatsächlich die Ausnahmen ein Application.Run oder Application.DoEvents rufen lassen. Im Release-Modus geschieht dies nicht, und die Ausnahmen haben ‚gefangen‘ das Application.ThreadException Ereignis mit werden.

Nun aber ich bemerkte, dass das Ausnahmeobjekt in dem ThreadExceptionEventArgs des Application.ThreadException Ereignisses vergangen ist immer die innerste Ausnahme in der Ausnahmekette . Für die Protokollierung / Debugging / Design-Zwecke will ich wirklich die gesamte Kette von Ausnahmen though. Es ist nicht leicht zu bestimmen, welche externes System zum Beispiel schlug fehl, wenn Sie nur eine Socket Griff bekommen: wenn es wie zum Beispiel gewickelt ist ein NpgsqlException, dann zumindest wissen Sie, es ist ein Datenbankproblem.

So, wie auf die gesamte Kette von Ausnahmen von dieser Veranstaltung zu bekommen? Ist es überhaupt möglich, oder muß ich meine excepion in einer anderen Art und Weise der Handhabung gestalten?

Beachten Sie, dass ich -sort tun von- Abhilfe mit Application.SetUnhandledExceptionMode , aber dies bei weitem nicht ideal ist, weil ich muss meine eigene Nachrichtenschleife rollen.

EDIT: mehr Fehler zu vermeiden, die GetBaseException () -Methode nicht tut, was ich will : es gibt nur die innerste Ausnahme, während das einzige, was habe ich schon die innerste Ausnahme. Ich mag an der äußersten Ausnahme erhalten!

War es hilfreich?

Andere Tipps

Ich habe versucht, dieses Verhalten zu reproduzieren (immer die innerste Ausnahme bekommen), Frankreich aber ich bekomme die Ausnahme, die ich erwarten, mit allen Innerexceptions intakt.

Hier ist der Code I-Test verwendet:

   Private Shared Sub Test1()
      Try
         Test2()
      Catch ex As Exception
         Application.OnThreadException(New ApplicationException("test1", ex))
      End Try
   End Sub

   Private Shared Sub Test2()
      Try
         Test3()
      Catch ex As Exception
         Throw New ApplicationException("test2", ex)
      End Try
   End Sub

   Private Shared Sub Test3()
      Throw New ApplicationException("blabla")
   End Sub

Private Shared Sub HandleAppException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
...
End Sub

Unter HandleAppException Griffe Application.ThreadException. Die Test1 () -Methode aufgerufen zuerst.
Dies ist das Ergebnis (e As ThreadExceptionEventArgs) bekomme ich in HandleAppException:

Thread http://mediasensation.be/dump/?download=ThreadException.jpg

Wenn Sie nur Ausnahmen fangen und (Wieder-) werfen, wil keine Innerexceptions auftauchen, aber es wird auf die Ausnahme angehängt werden Stacktrace , wie folgt aus:.

  

bei SO.Test3 () in Test.vb: Linie 166
  bei SO.Test2 () in Test.vb: Linie 159
  bei SO.Test1 () in Test.vb: Linie 151

Normalerweise verlierst du nur die ganze Ausnahme Kette mit Ausnahme der Basis Ausnahme in einem Application.ThreadException Exception-Handler, wenn die Ausnahme in einem anderen Thread passiert ist.

Aus dem MSDN Library :

  

Mit diesem Ereignis können Sie Ihre Windows Forms   Anwendung zu handhaben anders   unbehandelte Ausnahmen, die auftreten, in    Windows Forms Fäden. Bringen Sie Ihre   Event-Handler zum Thread   Ereignis mit diesen Ausnahmen zu behandeln,   die verlassen wird Ihre Anwendung in   ein unbekannter Zustand. Wo möglich,   Ausnahmen sollten durch ein behandelt werden   strukturierte Ausnahmebehandlung Block.

Lösung: Wenn Sie Einfädeln, stellen Sie sicher, dass alle Fäden / Asynchron-Anrufe in einem try / catch-Block sind. Oder wie Sie gesagt haben, können Sie mit Application.SetUnhandledExceptionMode spielen.

Nur etwas Interessantes entdeckt. Verschiedene GUI-Ereignisse werden Sie unterschiedliche Ergebnisse erhalten. Eine Ausnahme von einem Handler wird in Application.ThreadException Ereignisse Form.Shown geworfen führt die inner meisten Ausnahme abfangen, aber genau die gleiche Code läuft in der Form.Load Veranstaltung wird in dem Außen meist Exception immer in Application.ThreadException gefangen.

Haben Sie die Exception.GetBaseException Methode versucht? Dies gibt die Ausnahme, die die Application.TreadException erstellt. Sie könnten dann den gleichen Prozess verwenden, um die Kette zu gehen, um alle Ausnahmen zu bekommen.

exception.getbaseexception Methode

Basierend auf einige der Informationen in dieser Kette, benutzen ich UnhandledExceptionMode.ThrowException zu UnhandledExceptionMode.CatchException gegenüber. Ich fange dann die Ausnahme außerhalb der Run Form () und das gibt mir die gesamte Kette von Ausnahmen.

Nach der MSDN-Dokumentation:

Wenn in einer abgeleiteten Klasse überschreibt, Exception zurück, die die Ursache für eine oder mehr nachfolgenden Ausnahmen ist.

    Public Overridable Function GetBaseException() As Exception
        Dim innerException As Exception = Me.InnerException
        Dim exception2 As Exception = Me
        Do While (Not innerException Is Nothing)
            exception2 = innerException
            innerException = innerException.InnerException
        Loop
        Return exception2
    End Function

Sie können eine Variation dieses verwenden, um die Ausnahme Kette zu analysieren.

Public Sub LogExceptionChain(ByVal CurrentException As Exception)

    Dim innerException As Exception = CurrentException.InnerException
    Dim exception2 As Exception = CurrentException

    Debug.Print(exception2.Message) 'Log the Exception

    Do While (Not innerException Is Nothing)

        exception2 = innerException
        Debug.Print(exception2.Message) 'Log the Exception

        'Move to the next exception
        innerException = innerException.InnerException
    Loop

End Sub

Das würde mich schlagen, wie genau das, was Sie suchen.

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