为什么在处理Action的方法中捕获会截断堆栈跟踪?

考虑这个小程序。 忽略,如果你愿意的话,通用捕获,我保持简短的尝试并说明要点:

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); } } 

运行时,会生成以下内容(删除一些路径信息):

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

我的问题是 – 为什么exception的堆栈跟踪会在Try()方法中解除方法链的展开? 我希望它能够通过Main()方法解除它。

我还没有找到任何关于什么是停止exception展开超过Try()文档 – 所以我想了解这一点。

Exception.Stacktrace调用最终会调用的GetStackTrace
new StackTrace(this /* exception object */, true) 。 当与这些参数一起使用时,将针对exception点评估堆栈跟踪,直到当前方法为止。 您可以在添加时自行检查

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

第二个版本是exc.StackTrace返回的exc.StackTrace ,第一个是从当前方法到入口点或线程启动的完整exc.StackTrace

这个:

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

Try捕获你的exception,并且不向上传播以解开callstack,它只是吞下exception。 因此,您不会将Main视为堆栈跟踪的一部分。 如果要查看Main ,请将catch留给Main方法:

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

现在你看到了:

在C:\ Users \ Yuval \ documents \ visual studio 14 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs中的ConsoleApplication2.Program.Fail()中:在C:\ Users \中的ConsoleApplication2.Program.Try(Action action)第25行Yuval \ documents \ visual studio 14 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs:第30行,位于C:\ Users \ Yuval \ documents \ visual studio 14 \ Projects \ ConsoleApplication2中的ConsoleApplication2.Program.Main(String [] args) ConsoleApplication2 \ Program.cs:第15行