对 Exception.StackTrace 的内容感到困惑

发布于 2024-10-22 12:32:31 字数 1339 浏览 4 评论 0原文

假设我有以下情况:

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        }

我运行它并得到以下输出:

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

如果我取消注释,则抛出 new Exception("Case 1"); 输出是:

at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 15

所以我的问题是为什么在第一种情况下我可以看到包括 Main 函数的完整路径,而在第二种情况下我看不到相同的内容。 如果生产代码类似于第二种情况,如何显示更完整的信息。

Suppose I have the following situation:

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        }

I run it and have the following output:

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

If I uncomment throw new Exception("Case 1");
the output is:

at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 15

So my question is why in the first case I can see the full path including the Main function while I cannot see the same stuff in the second case.
How can I display the more complete information if the production code is similar to the second case scenario.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

≈。彩虹 2024-10-29 12:32:31

您在堆栈跟踪中看到的是编译器为您传递给 WrapperMethod 的匿名函数生成的名称。在这种情况下,除了不使用匿名函数之外,没有办法获得“更漂亮的名称”。

然而,当您知道这一点时,“在精神上解析”损坏的堆栈跟踪应该不难。您可以通过名称来识别匿名函数,该名称类似于

b__0(),并且您可以看出它是在 Program 类中声明的,因为它是编译器决定生成该函数的位置。

您不会丢失任何堆栈信息。如果 WrapperFunction 内部抛出异常,则该异常将位于最顶层的堆栈帧。如果 WrapperFunction 调用的方法内部引发异常,则该方法(在本例中为匿名)将位于堆栈的顶部。

What you are seeing in your stack trace is the compiler's generated name for the anonymous function you are passing into WrapperMethod. There is no way to get a "prettier name" in this situation, short of not using anonymous functions.

However, when you know this, it shouldn't be hard to "mentally parse" the mangled Stack Trace. You can recognize the anonymous function by it's name which will be something like <Main>b__0(), and you can tell it was declared inside the Program class because that is where the compiler decided to generate the function.

You are not losing any stack information. If an exception is thrown inside WrapperFunction, that will be the topmost stack frame. If an exception is thrown inside a method that WrapperFunction calls, that (in this case, an anonymous) method will be on top in the stack.

溺渁∝ 2024-10-29 12:32:31

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

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

In the first case you are making another method call to the anonymous method that is defined inside the Main method. As the exception is thrown inside the anonymous method, it's included in the call stack.

If you throw the exception in the WrapperMethod method, then the anonymous method is never involved, so it won't show up in the call stack.

花间憩 2024-10-29 12:32:31

您只能按原样看到堆栈跟踪,仅此而已。

原因是 Lambda 表达式在需要运行时会被抖动,在此之前它们仅以数据形式存储。

You are only seeing the stack trace as it is, nothing more nothing less.

The reason is Lambda expressions are jitted when they need to run and before that they are only stored in the form of data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文