我有如下代码来捕获使用TaskFactory和Task.Run创建的任务抛出的异常。如果我使用TaskFactory,我可以检查继续任务中从上一个任务抛出的异常,而不必使用Task.WaitAll方法。如果我使用Task.Run,则除非我明确等待子任务完成,否则将不会执行Continued任务。 TaskFactory.StartNew中的哪个标志改变了这种行为?
另外,AggregateException类中的InnerException和InnerExceptions有什么区别? InnerExceptions返回一个由子任务抛出的所有异常的只读集合。 InnerException返回仅由一个子任务抛出的异常的AggregateExcpetion。
//Use Factory
TaskCreationOptions atp = TaskCreationOptions.AttachedToParent;
Task.Factory.StartNew(() =>
{
Task.Factory.StartNew (() => { throw null; }, atp);
Task.Factory.StartNew (() => { throw new NullReferenceException();}, atp);
Task.Factory.StartNew (() => { throw new Exception("Test"); }, atp);
})
.ContinueWith (p => p.Exception.Dump(),TaskContinuationOptions.OnlyOnFaulted);
//Use Task.Run
Task.Run(()=>
{
TaskCreationOptions op = TaskCreationOptions.AttachedToParent;
var t1 = Task.Factory.StartNew(()=> {throw null;}, op);
var t2 = Task.Factory.StartNew(()=> {throw new NullReferenceException();}, op);
var t3 = Task.Factory.StartNew(()=> {throw new Exception("Test");}, op);
//This will trigger the continued task
//Task.WaitAll(new Task[]{t1,t2,t3});
}).ContinueWith(task => {task.Exception.Dump();}, TaskContinuationOptions.OnlyOnFaulted);
答案 0 :(得分:12)
InnerException
是Exception
的属性,返回'the exception that caused this exception'。 InnerExceptions
是AggregateException
独有的属性。由于其设计,汇总异常可能包含多个导致'异常。由于属性InnerException
是继承的,因此从InnerExceptions
返回第一个异常是有道理的。
要回答您的示例代码行为的其他问题,区别在于TaskCreationOptions
的{{1}}默认值。默认值为Task.Run
。您可以在this blog post中了解更多相关信息。