Повторная выдача исключения в задаче (TPL) теряет трассировку стека - PullRequest
3 голосов
/ 27 сентября 2011

У меня есть код, который перебрасывает исключение.

Когда я позже читаю исключение из task.Exception, его трассировка стека указывает на то место, куда я перебросил исключение (строка n, а не строка m, как я ожидал).

Почему это так? ошибка в TPL или, скорее всего, я что-то упустил.

В качестве обходного пути я могу обернуть исключение как внутреннее исключение в новое исключение.

internal class Program
{
    private static void Main(string[] args)
    {
        Task.Factory.StartNew(TaskMethod).ContinueWith(t => Console.WriteLine(t.Exception.InnerException));
        Console.Read();
    }

    private static void TaskMethod()
    {
        try
        {
line m:     throw new Exception("Todo");
        }
        catch (Exception)
        {
line n:     throw;
        }
    }
}

1 Ответ

3 голосов
/ 27 сентября 2011

К сожалению, из-за того, что TPL хранит исключения до завершения выполнения задачи, исходная трассировка стека теряется.Запуск вашего примера кода в LINQPad показывает, что исключение было выдано на at System.Threading.Tasks.Task.Execute(), что, очевидно, не правильно.

В качестве грубого обходного пути вы могли бы сохранить исходную трассировку стекапростая строка) в свойстве Data исходного исключения, и вы сможете получить к нему доступ:

private static void TaskMethod()
{
    try
    {           
        throw new Exception("Todo");
    }
    catch (Exception ex)
    {
        ex.Data["OriginalStackTrace"] = ex.StackTrace;
        throw;
    }
}

Тогда исходная трассировка стека будет храниться в OriginalStackTraceзначение словаря Data:

Это не совсем то, что вы хотите, но я надеюсь, что это поможет.

...