在任务中重新抛出exception(TPL)会丢失堆栈跟踪

我的代码重新抛出exception。

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

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

当我解决方法时,我可以将exception包装为新exception中的内部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; } } } 

不幸的是,由于TPL在任务完成执行之前存储exception的方式,原始堆栈跟踪将丢失。 在LINQPad中运行示例代码表明at System.Threading.Tasks.Task.Execute()抛出了exception,这显然是不正确的。

作为一种粗略的解决方法,您可以将原始堆栈跟踪(它是一个简单的字符串)存储在原始exception的Data属性上,然后您将能够访问它:

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

然后,您将原始堆栈跟踪存储在Data字典的OriginalStackTrace值中:

这不是你想要的,但我希望它有所帮助。