Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 任务中的重新抛出异常(TPL)丢失堆栈跟踪_C#_.net_Task_Task Parallel Library - Fatal编程技术网

C# 任务中的重新抛出异常(TPL)丢失堆栈跟踪

C# 任务中的重新抛出异常(TPL)丢失堆栈跟踪,c#,.net,task,task-parallel-library,C#,.net,Task,Task Parallel Library,我有一段代码可以重新引发一个异常 当我稍后从task.exception读取异常时,它的stacktrace指向我重新抛出异常的位置(如我所料,是第n行,而不是第m行) 为什么会这样?TPL中的bug或者更可能是我忽略的东西 作为解决方法,我可以将异常包装为新异常中的内部异常 internal class Program { private static void Main(string[] args) { Task.Factory.StartNew(TaskMe

我有一段代码可以重新引发一个异常

当我稍后从task.exception读取异常时,它的stacktrace指向我重新抛出异常的位置(如我所料,是第n行,而不是第m行)

为什么会这样?TPL中的bug或者更可能是我忽略的东西

作为解决方法,我可以将异常包装为新异常中的内部异常

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

不幸的是,由于TPL在任务完成执行之前存储异常的方式,原始堆栈跟踪丢失。在LINQPad中运行示例代码表明异常是在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
值中:


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

替换行号的问题是众所周知的。有人在讨论一个可能的解决办法,但我自己还没有用过。现在我知道事情就是这样。我想我会像抛出新异常一样包装异常(“参见内部异常”,e);