Неправильная трассировка стека при повторном отбрасывании - PullRequest
36 голосов
/ 18 ноября 2010

Я перебрасываю исключение с помощью «throw;», но трассировка стека неверна:

static void Main(string[] args) {
    try {
        try {
            throw new Exception("Test"); //Line 12
        }
        catch (Exception ex) {
            throw; //Line 15
        }
    }
    catch (Exception ex) {
        System.Diagnostics.Debug.Write(ex.ToString());
    }
    Console.ReadKey();
}

Правильная трассировка стека должна быть:

System.Exception: Test
   at ConsoleApplication1.Program.Main(String[] args) in Program.cs:Line 12

Но я получаю:

System.Exception: Test
   at ConsoleApplication1.Program.Main(String[] args) in Program.cs:Line 15

Но строка 15 - это позиция "throw;". Я проверил это с .NET 3.5.

Ответы [ 12 ]

0 голосов
/ 19 января 2011

Я думаю, что это меньше случай изменения трассировки стека и больше касается способа определения номера строки для трассировки стека.Испытание в Visual Studio 2010, поведение похоже на то, что вы ожидаете от документации MSDN: "throw ex;"перестраивает трассировку стека с точки этого оператора "throw;"оставляет трассировку стека такой, какой она есть, за исключением того, что когда бы ни возникало исключение, номер строки - это место повторного выброса, а не вызов, через который произошло исключение.

То же самое с «throw;»дерево вызовов методов остается неизменным, но номера строк могут измениться.

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

Как говорили многие другие, обычно этоЛучше всего не ловить исключение, если вы действительно не обязаны это делать, и / или вы собираетесь с ним разобраться на этом этапе.

Интересное примечание: Visual Studio 2010 даже не позволит мне построить код в том виде, как он представленв вопросе, так как он поднимает ошибку деления на ноль во время компиляции.

0 голосов
/ 18 ноября 2010

Это потому, что вы поймали Exception из строки 12 и перебросили его на линии 15 , поэтому трассировка стека воспринимается как наличные, что Exceptionброшенный оттуда.

Чтобы лучше обрабатывать исключения, вы должны просто использовать try...finally и позволить необработанному Exception всплыть.

...