2015-04-16 7 views
5

HINWEIS NACH LÖSUNG HINZUGEFÜGT: Eine AccessViolationException wurde innerhalb der von reflection aufgerufenen Methode ausgelöst. Aus diesem Grund konnte die TargetInvocationException nicht abgefangen werden.System.Reflection.TargetInvocationException wird nicht abgefangen

HINWEIS: Dies ist außerhalb der IDE. The referenced question is NOT the same.

TL; DR

  1. kann nicht einen Stack-Trace erhalten
  2. nicht innere Ausnahmen
  3. Debugger (Kopierschutzes eines Dritten Bibliothek verwenden kann nicht bekommen wird (in der Art)
  4. Alle Änderungen am Code verhindern, dass die Ausnahme auftritt - bedeutet, dass ich keine Protokollierung hinzufügen kann, um herauszufinden, wo die Ausnahme auftritt

Wie bekomme ich die Ausnahme, um erwischt zu werden oder die benötigten Informationen auf andere Weise zu bekommen?

Lange Beschreibung:

Ich habe ein Problem mit einer Ausnahme, die in einem Verfahren auftritt, die durch Reflexion aufgerufen wird. Die Ausnahme selbst tritt tatsächlich in der aufgerufenen Methode auf, aber da die Methode durch Reflektion aufgerufen wird, wird die echte Ausnahme in eine System.Reflection.TargetInvocationException eingeschlossen. Kein Problem, fangen Sie es einfach und erhalten Sie die interne Ausnahme - außer die System.Reflection.TargetInvocationException wird nicht erwischt. Mein Programm stürzt ab, und ich bekomme einen Dump zusammen mit einem Eintrag im Windows-Ereignisprotokoll.

Das Windows-Ereignisprotokoll enthält nicht die internen Ausnahmen und auch nicht das Abbild. Ich kann keinen Debugger an das Programm anhängen, weil dann eine externe Bibliothek (die benötigt wird, um zum Reflection Call zu kommen) nicht läuft - Kopierschutz, weißt du nicht. Wenn ich einen Versuch/Catch in die beleidigende Methode eingibt, tritt die Ausnahme nicht auf - was schlecht ist. Die Ursache ist nicht festgelegt, es passiert einfach nicht mehr. Derselbe Effekt tritt auf, wenn ich die Protokollierung in die beleidigende Methode einfüge - die Ausnahme tritt nicht mehr auf.

Ich kann die Protokollierung nicht verwenden, ich kann keinen Debugger verwenden, und an der einen Stelle, wo ich die Ausnahme abfangen und protokollieren konnte, wird die Ausnahme nicht erwischt.

Ich verwende Visual Studio 2010 und Dotnet 4.0.

Um es zu verdeutlichen: Die try/catch funktioniert nicht, wenn das Programm außerhalb von Visual Studio ausgeführt wird, und ich kann es nicht innerhalb von Visual Studio im Debugger ausführen, weil das Programm dann nicht erreichen kann zeigen Sie an, wo die Ausnahme auftritt. Dies ist NICHT in der IDE.

die Reflexion Beseitigung nicht möglich ist (ich habe es versucht, nur einen Fall, und die Ausnahme geht weg.)

Verfahren eine Menge Sachen tut genannt zu werden, aber es brechen in kleinere Methoden helfen nicht - die Ausnahme geht einfach weg.

Die Ausnahme tritt nicht die ganze Zeit auf, nur wenn ich eine bestimmte Reihenfolge von Schritten mache - und wenn sie auftritt, dann ist es immer das zweite Mal durch die ganze Sequenz.

In der Sequenz, die ich verwende, wird die Methode von zwei Threads fast gleichzeitig aufgerufen - ein bestimmter Datenblock wird eingegeben, der eine Kopie eines Berichts und eines anderen Dokuments auf zwei separaten Druckern erstellt - einen Bericht und Dokument zu jedem Drucker. Da das Generieren der Berichte und das Drucken des Dokuments eine Weile dauern können, werden sie im Hintergrund auf Threads ausgeführt, damit der Benutzer weiterarbeiten kann.

Ich vermute, dass die Threads auf die anderen Zehen treten (viele Datei- und Datenbankmanipulationen gehen weiter), aber ohne zu wissen, was wirklich passiert, kann ich es nicht beheben.

Der folgende Code zeigt eine vereinfachte Version des Anrufs durch Reflektion.

Hat jemand einen Vorschlag, was die System.Reflection.TargetInvocationException nicht gefangen werden könnte, oder vielleicht eine alternative Möglichkeit, die innere Ausnahme zu fangen?

Try 
    Dim methode As System.Reflection.MethodInfo 
    methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static) 
    Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing) 
    result = DirectCast(resultobject, DataSet) 
Catch ex As Exception 
    'Log the error here. 
End Try 
+0

mögliche Duplikate von [Warum wird TargetInvocationException von der IDE als nicht abgefangen behandelt?] (Http://stackoverflow.com/questions/2658908/why-is-targetinvocationexception-treated-as-uncaught-by-the-ide) –

+1

Kein Duplikat, da dies außerhalb der IDE erfolgt. – JRE

+1

Dies ist eine Menge Text, mit sehr wenig Informationen, die es jedem erlauben würden, den Grund zu erraten. Es gibt keinen Stack-Trace. Es gibt keinen Code, der tatsächlich Teil Ihres Problems ist. Sie erwähnen Dinge, die in Threads ausgeführt werden, aber nicht wie. Bitte geben Sie die relevanten Informationen an. – Alex

Antwort

8

gefunden der Grund, warum ich nicht die Ausnahme abfangen könnte:

Die eigentliche Ausnahme war ein Access, die ohne besondere Schritte (How to handle AccessViolationException.)

in Dotnet 4.0 gefangen kann nicht sein Wenn AccessViolationException in einer von reflection aufgerufenen Methode ausgelöst wird, wird nur eine TargetInvocationException im Windows-Ereignisprotokoll protokolliert, und nur die TargetInvocationException ist im Dump verfügbar.

Sobald ich es geschafft habe, die echte Ausnahme zu bekommen, fand ich, dass es ein Aufruf von Application.DoEvents() von einem Nicht-GUI-Thread war, der die AccessViolation verursachte. DoEvents() kann genug Spaß machen, wenn es auf dem GUI-Thread (Use of Application.DoEvents()) aufgerufen wird, geschweige denn, wenn es von einem Hintergrund-Thread aufgerufen wird.

Sobald das behoben war, fand ich, dass unsere Third-Party-Bibliothek (die mit dem Kopierschutz) nicht gerne gleichzeitig in getrennten Instanzen aufgerufen wird. Das zu beheben war eine Sache einer Synclock am richtigen Ort.

Der Code, der all diesen Spaß verursacht hat, war einmal alle im GUI-Thread und wurde ursprünglich in den Tagen von dotnet 1.1 geschrieben - dies erklärt den Aufruf von DoEvents. Der Code wurde stückweise so konvertiert, dass er parallel in Hintergrundthreads über mehrere verschiedene Stufen läuft, wobei kein einziger Entwickler einen vollständigen Überblick über den Prozess hat.

+0

Wie hast du das Problem gelöst? Das gleiche Problem tritt auf, wenn TIE nur im Windows-Ereignisprotokoll angezeigt wird. – ChaseMedallion

+0

Hinzufügen Try/catch (falls Sie es noch nicht haben) dann folgen Sie den Anweisungen hier (http://stackoverflow.com/a/4759831/ 3945058), um das Abfangen der "korrupten Status" -Ausnahmen zu ermöglichen. – JRE

+0

Hallo, dies scheint zu sein [mein Problem zu] (http://stackoverflow.com/q/39954552/1488067), bemerkte ich die "AccessViolationException" in der Windows-Fehlerberichtsprotokoll direkt nach meiner Ausnahme. Eine Sache ist nicht ganz klar, wenn Sie es klarstellen können: passierte Ihre Ausnahme tatsächlich an dem Punkt, der mit dem Stack-Trace gezeigt wurde, oder trat sie bei einem völlig anderen Thread auf und schien nur innerhalb Ihrer Methode zu versagen? Wie hast du es geschafft, die "echte Ausnahme" zu bekommen? – Lou

0

Ich bin nicht sicher, ob ich das Problem replizieren kann, aber das ist, wie wir es bekommen und es funktioniert ist gut so ...

Try 
    'YOUR CODE' 
Catch ex As Exception 
    'This is where we grab it from... It needs to be in this block to work... 
    System.Reflection.MethodInfo.GetCurrentMethod.ToString 
End Try 

Lassen Sie mich wissen, wie es die Arbeit für Sie?

+0

Wie gesagt, der Haken fängt nichts ein, das Programm stürzt einfach ab. Alles, was ich bekomme, ist ein Windows-Ereignisprotokolleintrag, der besagt, dass ein Programm abgestürzt ist und mir sagt, welche Art von Ausnahme es war. – JRE

+0

Also ist es eine andere Art von Ausnahme dann, deshalb ist es nicht gefangen ... Zeigen Sie, was Code in diesem Block ist ... – Codexer

+0

Kann nicht, es ist mehrere hundert Zeilen lang und enthält Aufrufe an andere Methoden. Alte Sünden, die ich nicht begangen habe, sondern mit denen ich leben muss. Es ist auch definitiv System.Reflection.TargetInvocationException, aber es wird durch etwas innerhalb der reflektierten Methode verursacht. Der Typ spielt sowieso keine Rolle - Catch ex als Exception sollte jede Art von Ausnahme erfassen. – JRE

Verwandte Themen