2014-11-17 12 views
5

Rozważ ten mały program. Zignorować, jeśli będzie ogólny połów, ja trzymał go krótko, aby spróbować zilustrować punkt:Dlaczego przechwycić metodę obsługującą działanie obcięcie śledzenia stosu?

private static void Main(string[] args) 
{ 
    Try(Fail); 
} 

private static void Fail() 
{ 
    var x = ((string)null).Clone(); 
} 

private static void Try(Action action) 
{ 
    try 
    { 
     action(); 
    } 
    catch (Exception exc) 
    { 
     Debug.WriteLine(exc.StackTrace);     
    } 
} 

Po uruchomieniu następujące (niektóre z informacji ścieżki usunięty) jest produkowany:

at Scratch.Program.Fail() in Program.cs:line 27 
at Scratch.Program.Try(Action action) in Program.cs:line 34 

Moje pytanie brzmi: dlaczego śledzenie stosu wyjątku powoduje zatrzymanie rozwijania łańcucha metod przy metodzie Try()? Spodziewam się, że rozwinie się to po metodzie Main().

Nie udało mi się znaleźć żadnej dokumentacji na temat tego, co powstrzymuje wyjątek od rozwijania się po przejściu obok Try() - więc chciałbym to zrozumieć.

+5

Łapiesz wyjątek w 'Try()', jeśli złapałeś go w 'Main()', to tam kończy się ślad stosu. –

+2

To w rzeczywistości nie ma nic wspólnego z 'Akcja', zdarza się, nawet jeśli po prostu masz' Try' zadzwoń 'Fail' bezpośrednio: http://ideone.com/X9JQFS –

Odpowiedz

2

Exception.Stacktrace wzywa GetStackTrace który w końcu zadzwonić
new StackTrace(this /* exception object */, true). W przypadku użycia z tymi parametrami śledzenie stosu będzie oceniane dla punktu wyjątku, aż do bieżącej metody. Można sprawdzić, że sam podczas dodawania

catch (Exception exc) 
{ 
    Debug.WriteLine(new StackTrace()); 
    Debug.WriteLine(new StackTrace(exc, true));   
} 

Druga wersja jest StackTrace zwrócony przez exc.StackTrace, pierwszy jest pełen StackTrace od dotychczasowego sposobu do punktu wejścia lub początek gwintu.

+0

Akceptuję to, ponieważ odpowiada pytanie, nie pozostawiając mi żadnych dalszych pytań - wielkie dzięki. –

4

to:

try 
{ 
    action(); 
} 
catch (Exception exc) 
{ 
    Debug.WriteLine(exc.StackTrace);     
} 

łapie swój wyjątek wewnątrz Try, a nie propagować górę na odpoczynek callstack, to po prostu połyka wyjątek. Dlatego nie widzisz Main jako części twojego stacktrace. Jeśli chcesz zobaczyć Main pozostawić catch do sposobu Main:

public static void Main(string[] args) 
{ 
    try 
    { 
     Try(Fail); 
    } 
    catch (Exception e) 
    { 
    } 
} 

A teraz patrz:

na ConsoleApplication2.Program.Fail() w C: \ Users \ \ Yuval dokumenty \ studio wizualne 14 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs: line 25 at ConsoleApplication2.Program.Try (akcja) w C: \ Users \ Yuval \ documents \ visual studio 14 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program. CS: linia 30 na ConsoleApplication2.Program.Main (String [] args) w C: \ Users \ Yuval \ Documents \ visual studio 14 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs: linia 15

Powiązane problemy