2010-06-16 5 views
21

Aktualizacja: Mam złożył raport o błędzie na Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#detailsnieuchwytny wyjątek, pkt 2

Jeśli można odtworzyć ten problem na komputerze, proszę upvote bug więc można go naprawić!


Ok zrobiłem kilka testów i mam problem zmniejszona do czegoś bardzo prostego:

ja. Utwórz metodę w nowej klasie, która zgłasza wyjątek:

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

ii. Utwórz MethodInfo, która wskazuje na tę metodę w innym miejscu:

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

iii. Zawijanie wywołania Invoke() w bloku try/catch:

try { 
    method.Invoke(obj, null); // exception is not being caught! 
} catch { 
} 

iv. Uruchom program bez debuggera (działa dobrze).

v. Uruchom teraz program z debugerem. Debugger zatrzyma program, gdy wystąpi wyjątek, mimo że jest zawijany w procedurze catch, która próbuje go zignorować. (Nawet jeśli umieścisz punkt przerwania w bloku catch, zatrzyma się zanim dotrze do niego!)

W rzeczywistości wyjątek ma miejsce, gdy uruchamiasz go bez debuggera. W prostym projekcie testowym jest ignorowany na jakimś innym poziomie, ale jeśli twoja aplikacja ma jakąkolwiek globalną obsługę wyjątków, zostanie tam również wywołana. [Zobacz komentarze]

To jest przyczyną mnie prawdziwy ból głowy, ponieważ utrzymuje wyzwalanie zderzeniowych obsługi mojej aplikacji, nie wspominając o bólu to jest próba debugowania.

+7

+1 bo wziął czas, aby zmniejszyć to na przykład –

+0

Zobacz sane tutaj : http://stackoverflow.com/questions/2724703/why-does-vs2010-always-break-on-exception-from-methodinfo-inoke –

+4

Czy włączono wyjątek jako "zatrzymaj przy rzucaniu" w Visual Studio? to zachowanie, przejdź do Debug | Exceptions i odznacz opcję stop on throw. –

Odpowiedz

5

Mogę odtworzyć to na moim .NET 4 box, i masz rację - dzieje się to tylko na .NET 4.0.

To pachnie bardzo jak błąd do mnie i powinien przejść na MS Connect. Major bummer, jeśli to potknie się o twój moduł obsługi wypadków. Wygląda na to, że nie jest przyjemnym sposobem obejścia tego problemu, to owinięcie wywoływanej metody wewnątrz własnego programu obsługi. :-(

Jedno I nie można odtworzyć, choć jest wyzwalania obsługi katastrofy Tu jest mój program..

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

Nie udało mi się jeszcze odtworzyć błędu obsługi zderzenia w aplikacji testowej, ale pracuję nad tym. Z jakiegoś powodu moja prawdziwa aplikacja umiera dość mocno, a wyjątek (który wydrukuję do pliku dziennika) wygląda bardzo podobnie. – devios1

+0

Zrobiłem jednak odkryć coś innego interesującego: jeśli powiążesz właściwość w WPF, która zgłasza wyjątek, debugger zatrzyma się również tam, kiedy go uruchomisz - nie musisz nawet wywoływać MethodInfo.Invoke w ogóle! Zderzenie sterownika awarii, gdy nie jest w trybie debugowania, wydaje się być fałszywe, ponieważ okazuje się, że jest to inny problem powodujący to - co oznacza, że ​​może to być błąd VS2010. – devios1

+0

Ta odpowiedź to ten sam wynik, który otrzymuję. Zasadniczo w "Invoke" jest coś, co wydaje mi się, że teraz bardzo żałują, ale nie powoduje to bólu głowy. NB. Wierzę, że dokładnie, kiedy program obsługi UnhandledException zostanie wykonany, zależy od wersji systemu Windows! Możesz więc uzyskać różne wyniki na XP/Vista/7. Moje testowanie ma wartość 7, a zdarzenie UnhandledException nigdy się nie uruchamia, ale zatrzymuje się w debugerze. –

-1

Nie można przechwycić wszystkich wyjątków. W twoim przykładzie jest kilka założeń. Na przykład zakładasz, że wyjątek został zgłoszony w wątku wywołującym. Przechwytywanie nieobsłużonych wyjątków w innych wątkach zależy od używanych środowisk wykonawczych (konsoli, winform, WPF, ASP.Net itd.).

Ponadto wywołania System.Environment.FailFast() nie generują warunku dającego się obsłużyć - proces jest skutecznie kończony bez szansy na interwencję.

+0

Wzywa Invoke(), a nie BeginInvoke(), więc wywołanie odbywa się w bieżącym wątku. Jest jednak pewien zewnętrzny kod, który wchodzi między wywołania, gdy wywołanie jest wykonywane. –

+0

@Dave, ale to nie gwarantuje, że wywołana metoda nie spowoduje utworzenia innego wątku. Moje stwierdzenie powyżej ma znaczenie. –

+0

@Dave, przez to, mam na myśli, metoda wywołana przez 'Invoke', mogłaby z kolei utworzyć wątek (bezpośrednio lub pośrednio), nie mam na myśli, że' Invoke', sam, arbitralnie stworzy kolejny wątek. –

Powiązane problemy