对Exception.StackTrace的内容感到困惑

Eug*_*ica 8 c# clr

假设我有以下情况:

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函数在内的完整路径,而在第二种情况下我看不到相同的东西.如果生产代码与第二种情况类似,如何显示更完整的信息.

dri*_*iis 7

您在堆栈跟踪中看到的是编译器为您传递给WrapperMethod的匿名函数生成的名称.在没有使用匿名函数的情况下,没有办法在这种情况下得到一个"更漂亮的名字".

但是,当你知道这一点时,不应该"精神上解析"受损的Stack Trace.您可以通过它的名称来识别匿名函数,它<Main>b__0()可以告诉它是在Program类中声明的,因为这是编译器决定生成函数的地方.

您没有丢失任何堆栈信息.如果在WrapperFunction内抛出异常,那将是最顶层的堆栈帧.如果在WrapperFunction调用的方法内抛出异常,那么(在这种情况下,匿名)方法将位于堆栈的顶部.

  • 他正在谈论丢失WrapperMethod上方的堆栈跟踪.他希望能够一直追溯到Main中的方法调用. (3认同)

Guf*_*ffa 1

在第一种情况下,您将对方法内部定义的匿名方法进行另一个方法调用Main。由于异常是在匿名方法内部引发的,因此它包含在调用堆栈中。

如果在方法中抛出异常WrapperMethod,则永远不会涉及匿名方法,因此它不会显示在调用堆栈中。

  • @Jenea:如果您在调试模式下运行代码,您还将在堆栈跟踪的 Main 方法中获得该点。它在发布模式下不显示的原因是,它内联的方法中的代码太少了。它实际上不存在于编译的代码中。 (2认同)