Consider this small program. Ignore, if you will, the generic catch, I've kept it brief to try and illustrate the point:
考虑这个小程序。如果你愿意的话,忽略这个普遍的问题,我简短地说明了这一点:
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);
}
}
When run, the following (with some of the path info removed) is produced:
当运行时,将产生以下内容(删除一些路径信息):
at Scratch.Program.Fail() in Program.cs:line 27
at Scratch.Program.Try(Action action) in Program.cs:line 34
My question is - why does the stack trace of the exception stop unwinding the method chain at the Try()
method? I would expect it to unwind past that to the Main()
method.
我的问题是-为什么异常的堆栈跟踪停止在Try()方法中展开方法链?我希望它可以unwind到Main()方法。
I haven't been able to find any documentation about what it is that stops exception unwinding going past the Try()
- so I'd like to understand this.
我还没有找到任何关于通过Try()停止异常解除的文档——所以我想理解这一点。
2 个解决方案
#1
2
Exception.Stacktrace
calls GetStackTrace
which in the end will callnew StackTrace(this /* exception object */, true)
. When used with these parameters the stack trace will be evaluated for the point of the exception until the current method. You can check that yourself when adding
例外。Stacktrace调用GetStackTrace,最终将调用新的Stacktrace (this /* exception对象*/,true)。当与这些参数一起使用时,堆栈跟踪将被计算为异常点,直到当前方法。您可以在添加时自己检查一下
catch (Exception exc)
{
Debug.WriteLine(new StackTrace());
Debug.WriteLine(new StackTrace(exc, true));
}
The second version is the stacktrace returned by exc.StackTrace
, the first is the full stacktrace from the current method to the entry point or thread start.
第二个版本是exc.StackTrace返回的stacktrace,第一个版本是从当前方法到入口点或线程启动的完整stacktrace。
#2
4
This:
这样的:
try
{
action();
}
catch (Exception exc)
{
Debug.WriteLine(exc.StackTrace);
}
catches your exception inside Try
, and doesn't propagate upwards to unwind the callstack, it simply swallows the exception. Therefor, you don't see Main
as part of your stacktrace. If you want to see Main
, leave the catch
to your Main
method:
在Try中捕获异常,并没有向上传播以展开调用堆栈,它只是吞掉异常。因此,您不会将Main视为stacktrace的一部分。如果你想看Main,把catch留给你的Main方法:
public static void Main(string[] args)
{
try
{
Try(Fail);
}
catch (Exception e)
{
}
}
And now you see:
现在你看到的:
at ConsoleApplication2.Program.Fail() in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 25 at ConsoleApplication2.Program.Try(Action action) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 30 at ConsoleApplication2.Program.Main(String[] args) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 15
在ConsoleApplication2.Program.Fail()C:\Users\Yuval\documents\visual工作室14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:ConsoleApplication2.Program第25行。试(Action行动)在C:\Users\Yuval\documents\visual studio 14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:线在ConsoleApplication2.Program 30。在工作室C:\Users\Yuval\documents\visual Main(String[]args)14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:第15行
#1
2
Exception.Stacktrace
calls GetStackTrace
which in the end will callnew StackTrace(this /* exception object */, true)
. When used with these parameters the stack trace will be evaluated for the point of the exception until the current method. You can check that yourself when adding
例外。Stacktrace调用GetStackTrace,最终将调用新的Stacktrace (this /* exception对象*/,true)。当与这些参数一起使用时,堆栈跟踪将被计算为异常点,直到当前方法。您可以在添加时自己检查一下
catch (Exception exc)
{
Debug.WriteLine(new StackTrace());
Debug.WriteLine(new StackTrace(exc, true));
}
The second version is the stacktrace returned by exc.StackTrace
, the first is the full stacktrace from the current method to the entry point or thread start.
第二个版本是exc.StackTrace返回的stacktrace,第一个版本是从当前方法到入口点或线程启动的完整stacktrace。
#2
4
This:
这样的:
try
{
action();
}
catch (Exception exc)
{
Debug.WriteLine(exc.StackTrace);
}
catches your exception inside Try
, and doesn't propagate upwards to unwind the callstack, it simply swallows the exception. Therefor, you don't see Main
as part of your stacktrace. If you want to see Main
, leave the catch
to your Main
method:
在Try中捕获异常,并没有向上传播以展开调用堆栈,它只是吞掉异常。因此,您不会将Main视为stacktrace的一部分。如果你想看Main,把catch留给你的Main方法:
public static void Main(string[] args)
{
try
{
Try(Fail);
}
catch (Exception e)
{
}
}
And now you see:
现在你看到的:
at ConsoleApplication2.Program.Fail() in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 25 at ConsoleApplication2.Program.Try(Action action) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 30 at ConsoleApplication2.Program.Main(String[] args) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 15
在ConsoleApplication2.Program.Fail()C:\Users\Yuval\documents\visual工作室14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:ConsoleApplication2.Program第25行。试(Action行动)在C:\Users\Yuval\documents\visual studio 14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:线在ConsoleApplication2.Program 30。在工作室C:\Users\Yuval\documents\visual Main(String[]args)14 \ ConsoleApplication2 \ ConsoleApplication2 \ \项目计划。cs:第15行