Смущает содержание Exception.StackTrace - PullRequest
8 голосов
/ 17 марта 2011

Предположим, у меня следующая ситуация:

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

Если я раскомментирую, выведите новое исключение («Дело 1»); вывод:

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

Таким образом, мой вопрос заключается в том, почему в первом случае я вижу полный путь, включая функцию Main, а во втором случае не вижу того же самого. Как я могу отобразить более полную информацию, если производственный код похож на сценарий второго случая.

Ответы [ 3 ]

7 голосов
/ 17 марта 2011

То, что вы видите в своей трассировке стека, - это имя, сгенерированное компилятором для анонимной функции, которую вы передаете в WrapperMethod.В этой ситуации нет способа получить «красивее имя», если не использовать анонимные функции.

Однако, когда вы это знаете, не составит труда «мысленно разобрать» искаженную трассировку стека.,Вы можете распознать анонимную функцию по ее имени, которое будет выглядеть примерно так: <Main>b__0(), и вы можете сказать, что оно было объявлено внутри класса Program, потому что именно здесь компилятор решил сгенерировать функцию.

Выне теряют стековую информацию.Если исключение выдается внутри WrapperFunction, это будет самый верхний кадр стека.Если исключение выдается внутри метода, который вызывает WrapperFunction, этот (в данном случае анонимный) метод будет сверху в стеке.

1 голос
/ 17 марта 2011

В первом случае вы делаете еще один вызов метода для анонимного метода, который определен внутри метода Main. Поскольку исключение выдается внутри анонимного метода, оно включается в стек вызовов.

Если вы выбросите исключение в методе WrapperMethod, анонимный метод никогда не будет задействован, поэтому он не будет отображаться в стеке вызовов.

0 голосов
/ 17 марта 2011

Вы видите только трассировку стека как есть, не более и не менее.

Причина в том, что лямбда-выражения объединяются, когда они должны выполняться, а до этого они хранятся только в форме данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...