重新抛出异常的任务(TPL)失去堆栈跟踪 [英] Re-throw exception in task (TPL) loses stack trace

查看:225
本文介绍了重新抛出异常的任务(TPL)失去堆栈跟踪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有code,它重新抛出异常。

当我后来读到异常的task.Exception,它的堆栈跟踪点的地方,我的位置重新抛出异常(N线,而不是直线m,如我所料)。

为什么会这样呢?错误的TPL或者更可能的东西我都忽略了。

当我解决方法我可以包装异常的内异常的新异常。

 内部类节目
{
    私有静态无效的主要(字串[] args)
    {
        Task.Factory.StartNew(TaskMethod).ContinueWith(T => Console.WriteLine(t.Exception.InnerException));
        Console.Read();
    }

    私有静态无效TaskMethod()
    {
        尝试
        {
行M:抛出新的异常(待办事项);
        }
        赶上(例外)
        {
线N:扔;
        }
    }
}
 

解决方案

不幸的是,由于第三方物流的方式存储的异常,直到任务执行完毕,原来的堆栈跟踪丢失。运行您的样品code在LINQPad显示,异常被抛出在在System.Threading.Tasks.Task.Execute(),这显然是不正确的。

由于原油的解决方法,你的可以的存储原始的堆栈跟踪(它是一个简单的字符串)的原始异常的数据属性,你就可以访问它,那么:

 私有静态无效TaskMethod()
{
    尝试
    {
        抛出新的异常(待办事项);
    }
    赶上(例外前)
    {
        ex.Data [OriginalStackTrace] = ex.StackTrace;
        扔;
    }
}
 

那么你就必须存储在数据词典的 OriginalStackTrace 值的原始堆栈跟踪:

这不是你真正想要的,但我希望它能帮助。

I've code that rethrows an exception.

When I later read the exception from task.Exception, its stacktrace points to the location where I re-threw the exception (line n and not line m, as I expected).

Why is this so? bug in TPL or more likely something I have overlooked.

As I workaround I can wrap the exception as the inner-exception in a new exception.

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;
        }
    }
}

解决方案

Unfortunately, due to the way TPL stores exceptions until the task finished executing, the original stack trace is lost. Running your sample code in LINQPad shows that the exception was thrown at at System.Threading.Tasks.Task.Execute(), which is obviously not correct.

As a crude workaround, you could store the original stack trace (it being a simple string) on the Data property of the original exception, and you'll be able to access it then:

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

Then you'll have the original stack trace stored in the OriginalStackTrace value of the Data dictionary:

It's not really what you want, but I hope it helps.

这篇关于重新抛出异常的任务(TPL)失去堆栈跟踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆