2010-06-16 5 views
21

Update: ich einen Fehlerbericht an Microsoft Connect eingereicht haben: https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#detailsDie uncatchable Ausnahme, pt 2

Wenn Sie dieses Problem auf Ihrem Computer wiedergeben können, benutzen Sie bitte den Bug upvote so es behoben werden kann!


Ok Ich habe einige Tests gemacht, und ich habe das Problem zu etwas sehr einfach reduziert:

i. Erstellen Sie eine Methode in einer neuen Klasse, die eine Ausnahme auslöst:

ii. Erstellen Sie eine MethodInfo, die auf diese Methode woanders verweist:

Type class1 = typeof(Class1); 
Class1 obj = new Class1(); 
MethodInfo method = class1.GetMethod("CallMe"); 

iii. Umleiten eines Aufrufs an Invoke() in einem try/catch-Block:

iv. Führen Sie das Programm ohne den Debugger (funktioniert gut).

v. Führen Sie jetzt das Programm mit dem Debugger aus. Der Debugger wird das Programm anhalten, wenn die Ausnahme auftritt, obwohl es in einen Catch-Handler eingepackt ist, der versucht, es zu ignorieren. (Auch wenn Sie einen Haltepunkt im Catch-Block setzen, wird er anhalten, bevor er ihn erreicht!)

Tatsächlich tritt die Ausnahme auf, wenn Sie es auch ohne den Debugger ausführen. In einem einfachen Testprojekt wird es auf einer anderen Ebene ignoriert, aber wenn Ihre Anwendung eine globale Ausnahmebehandlung hat, wird sie auch dort ausgelöst. [siehe Kommentare]

Dies verursachen mir einen echten Kopfschmerzen, weil es Crash-Handler meiner App hält Auslösung, den Schmerz nicht zu erwähnen, es zu debuggen, um zu versuchen ist.

+7

+1 führen, dass Sie sich die Zeit nahmen diese in einem gesunden Beispiel zu reduzieren –

+0

hier ansehen : http://stackoverflow.com/questions/2724703/why-does-vs2010-always-break-on-exception-from-methodinfo-invoke –

+4

Haben Sie die Ausnahme als "Stop wenn Wurf" in Visual Studio zu stoppen Dieses Verhalten, gehen Sie zu Debug | Exceptions und deaktivieren Sie Stop bei throw. –

Antwort

5

Ich kann dies auf meiner .NET 4-Box reproduzieren, und Sie haben Recht - es passiert nur auf .NET 4.0.

Das riecht mir sehr nach einem Bug und sollte auf MS Connect gehen. Major Schade, wenn dies Ihren Crash-Handler stolpern wird. Klingt wie eine nicht-gefällige Art, dies zu umgehen, ist, die aufgerufene Methode in einen eigenen Handler zu verpacken. :-(

Eine Sache kann ich nicht reproduzieren, obwohl, ist die Crash-Handler Auslösung Hier ist mein Programm:..

namespace trash { 
    public class Class1 { 
     public void CallMe() { 
      string blah = null; 
      blah.ToLower(); 
     } 
    } 

    class Program { 
     static void Main(string[] args) { 
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);   
      var class1 = typeof(Class1); 
      var method = class1.GetMethod("CallMe"); 

      try { 
       var obj = new Class1(); 
       method.Invoke(obj, null); // exception is not being caught! 
      } 
      catch (System.Reflection.TargetInvocationException) { 
       Console.Write("what you would expect"); 
      } 

     } 

     static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { 
      Console.Write("it would be horrible if this got tripped but it doesn't!"); 
     } 
    } 
} 
+0

Ich konnte den Crash-Handler in einer Test-App nicht reproduzieren, aber ich arbeite daran. Aus irgendeinem Grund stirbt meine echte App ziemlich hart und die Ausnahme (die ich in eine Protokolldatei drucke) sieht sehr ähnlich aus. – devios1

+0

Ich entdeckte jedoch etwas anderes interessantes: Wenn Sie an eine Eigenschaft in WPF binden, die eine Ausnahme auslöst, wird der Debugger auch dort anhalten, wenn Sie ihn ausführen - Sie müssen nicht einmal MethodInfo.Invoke aufrufen! Der Crash-Handler, der nicht im Debug-Modus stolperte, scheint falsch zu sein, da sich herausstellt, dass es ein anderes Problem war, das das verursacht - das könnte ein VS2010-Bug sein. – devios1

+0

Diese Antwort ist das gleiche Ergebnis, das ich bekomme. Im Grunde gibt es irgendwo in "Invoke" einen Zwischenfall, etwas, von dem ich glaube, dass sie es jetzt ernsthaft bereuen, aber es verursacht kein Ende der Kopfschmerzen. NB. Ich glaube genau, wann der UnhandledException-Handler ausgeführt wird, hängt von der Version von Windows ab! Sie können also unter XP/Vista/7 unterschiedliche Ergebnisse erzielen. Mein Test ist auf 7 und das Ereignis UnhandledException wird nie ausgelöst, aber es stoppt im Debugger. –

-1

Sie können nicht alle Ausnahmen abfangen. In Ihrem Beispiel gibt es einige Annahmen. Sie gehen beispielsweise davon aus, dass die Ausnahme im aufrufenden Thread ausgelöst wurde. Das Abfangen unbehandelter Ausnahmen in anderen Threads hängt davon ab, welche Laufzeit Sie verwenden (Konsole, Winforms, WPF, ASP.Net usw.).

Darüber hinaus generieren Aufrufe von System.Environment.FailFast() keine handhabbaren Bedingungen - der Prozess wird effektiv beendet und es besteht keine Eingriffsmöglichkeit.

+0

Er ruft Invoke(), nicht BeginInvoke(), so dass der Aufruf auf dem aktuellen Thread geschieht. Es gibt jedoch einen externen Code, der zwischen den Aufruf gelangt, wenn der Aufruf ausgeführt wird. –

+0

@Dave, aber das garantiert nicht, dass die fragliche aufgerufene Methode nicht dazu führt, dass ein anderer Thread erstellt wird. Meine obige Behauptung gilt. –

+0

@Dave, ich meine, die von 'Invoke' aufgerufene Methode könnte wiederum einen Thread erstellen (direkt oder indirekt), ich meine nicht, dass' Invoke', selbst, willkürlich einen anderen Thread erstellt. –