24

Ich habe Code, der Reflektion verwendet, um Eigenschaftswerte von einem Objekt zu ziehen. In einigen Fällen sind die Eigenschaften Ausnahmen auslösen können, weil sie null Referenzen, etc. habenWarum wird TargetInvocationException von der IDE als nicht abgefangen behandelt?

object result; 
try 
{ 
    result = propertyInfo.GetValue(target, null); 

} 
catch (TargetInvocationException ex) 
{ 
    result = ex.InnerException.Message; 
} 
catch (Exception ex) 
{ 
    result = ex.Message; 
} 

Letztlich richtig der Code funktioniert, aber wenn ich unter dem Debugger leite:

Wenn die Eigenschaft eine Ausnahme auslöst, Die IDE wird in den Debugger eingefügt, als wäre die Ausnahme nicht abgefangen. Wenn ich nur auf Ausführen klicke, fließt das Programm durch und die Ausnahme tritt als TargetInvocationException mit der echten Ausnahme in der InnerException-Eigenschaft auf.

Wie kann ich dies verhindern?

Antwort

28

Dies scheint "von Design" zu sein. Was passiert, ist, dass Sie wahrscheinlich Menü WerkzeugeOptionenDebuggenAllgemeineAktivieren Just My-Code aktiviert haben.

Als How to: Break on User-Unhandled Exceptions heißt es:

Die DebugAusnahmen Dialog zeigt eine zusätzliche Spalte (Pause, wenn eine Ausnahme Benutzer unhandled ist), wenn auf "My-Code aktivieren Sie einfach".

Dies bedeutet im Wesentlichen, dass, immer wenn die Ausnahme die Grenze Ihres Codes verlässt (und in diesem Fall bis zum .NET Framework-Reflektionscode fällt), bricht Visual Studio, weil es denkt, dass die Ausnahme den Benutzer verlassen hat Code. Es weiß nicht, dass es später im Stapel in den Benutzercode zurückkehren wird.

So gibt es zwei Lösungen: Deaktivieren Mein Code nur in Menü WerkzeugeOptionenDebuggenAllgemeineoder Entfernen Sie das Kontrollkästchen aus dem User-unhandled .NET Framework Ausnahmen im Menü DebugAusnahmen Dialog.

+0

In der Tat, das half: Ich hatte irgendwo einen String Formatierungsfehler (versucht, eine TimeSpan im int-Format anzuzeigen, statt die Anzahl der Tage) und bekam diesen Fehler. Inner Ausnahme: falsche Formatzeichenfolge. Aber wie man findet, wo diese Formatierung getan wurde. Als ich das "nur meinen Code ermöglichte" anzeigte, zeigte die unbegangene Ausnahme sofort, dass dies das Problem war. –

4

EDIT: Ich habe es gerade selbst ausprobiert, und es sieht so aus, als ob Reflexion etwas anders behandelt wird. Man könnte sich einen Reflektionsaufruf als eine neue Ebene von "handled" vorstellen, was den Debugger anbelangt: nichts fängt diese Ausnahme ein, bevor es übersetzt und als TargetInvocationException erneut getauft wird, also bricht es ein. Ich weiß es nicht weiß, ob es irgendeinen Weg gibt, das zu verhindern - aber passiert es sehr oft? Wenn Sie regelmäßig viele Vorgänge durchführen, die zu Ausnahmen führen, möchten Sie vielleicht Ihr Design überdenken.


Ursprüngliche Antwort

zu Debug Go/Ausnahmen ... und sehen, was die Einstellungen. Sie werden dieses Verhalten sehen, wenn TargetInvocationException (oder etwas höher in der Hierarchie) das Kontrollkästchen "Geworfen" aktiviert hat.

+0

Der Anwendungsfall ist ein "Überwachungsfenster" für Variablen, die meine App verwendet. Um dem Benutzer den Status dessen zu zeigen, was in der Anwendung vor sich geht. Dies geschieht nur, wenn der Benutzer das Überwachungsfenster anfordert, aktualisiert zu werden. Zur Laufzeit ist es nicht wirklich ein Problem, da die Ausnahme letztendlich gefangen wird, aber während der Entwicklung ist es ein großer Schmerz, weil es mich immer wieder aus dem Rennen wirft! –

+1

Meine erste Jon Skeet Antwort! –

+0

@Jason: Ja, ich kann sehen, dass es ein Schmerz ist. Ich weiß nicht, wie ich es befürchte. Für die meisten Situationen ist es wahrscheinlich das richtige Verhalten. –