为什么在处理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行