假设我有以下情况:
9 class Program
10 {
11 public static void WrapperMethod(Action func)
12 {
13 try
14 {
15 //throw new Exception("Case 1");
16 func.Invoke();
17 }
18 catch (Exception ex)
19 {
20 Console.WriteLine(ex.StackTrace);
21 }
22 }
23
24 static void Main(string[] args)
25 {
26 WrapperMethod(() => { throw new Exception("Case 2"); });
27 }
28 }
Run Code Online (Sandbox Code Playgroud)
我运行它并具有以下输出:
at TestExceptions.Program.<Main>b__0() in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 26
at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 16
Run Code Online (Sandbox Code Playgroud)
如果我取消注释抛出新的异常("案例1"); 输出是:
at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 15
Run Code Online (Sandbox Code Playgroud)
所以我的问题是为什么在第一种情况下我可以看到包括Main函数在内的完整路径,而在第二种情况下我看不到相同的东西.如果生产代码与第二种情况类似,如何显示更完整的信息.
您在堆栈跟踪中看到的是编译器为您传递给WrapperMethod的匿名函数生成的名称.在没有使用匿名函数的情况下,没有办法在这种情况下得到一个"更漂亮的名字".
但是,当你知道这一点时,不应该"精神上解析"受损的Stack Trace.您可以通过它的名称来识别匿名函数,它<Main>b__0()
可以告诉它是在Program
类中声明的,因为这是编译器决定生成函数的地方.
您没有丢失任何堆栈信息.如果在WrapperFunction内抛出异常,那将是最顶层的堆栈帧.如果在WrapperFunction调用的方法内抛出异常,那么(在这种情况下,匿名)方法将位于堆栈的顶部.
在第一种情况下,您将对方法内部定义的匿名方法进行另一个方法调用Main
。由于异常是在匿名方法内部引发的,因此它包含在调用堆栈中。
如果在方法中抛出异常WrapperMethod
,则永远不会涉及匿名方法,因此它不会显示在调用堆栈中。