我尝试将Task.ContinueWith
与TaskContinuationOptions.AttachedToParent
一起使用来执行延续任务,例如
Task outerTask = new Task(() => Console.WriteLine("Outer"));
Task innerTask = outerTask.ContinueWith(t =>
{
Thread.Sleep(500);
Console.WriteLine("Inner");
},
TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnRanToCompletion);
outerTask.Start();
outerTask.Wait();
Console.WriteLine("Outer done");
此代码的输出为
Outer
Outer done
Inner
但我期望/试图实现的是
Outer
Inner
Outer done
是否可以使用AttachedToParent
阻止外部任务完成,或AttachedToParent
仅对嵌套任务有效?
编辑:
我想要实现的目标是,当outerTask
成功完成时,我希望运行一个延续任务。我希望outerTask
将异常从innerTask
传播到调用者,而不必处理innerTask
。如果outerTask
失败,则应立即抛出异常(outerTask.Wait()
而不调用innerTask
)。
答案 0 :(得分:7)
您的代码中没有父子任务 您可能想要检查内部或子任务是什么,可以是两种类型:
attached child task or simply child task,在这种情况下如果子任务抛出一个未处理的异常,它将被父级捕获并重新抛出
更新
“是否可以使用AttachedToParent来阻止外部任务 完成......“
“我想在outerTask运行时运行一个延续任务 成功完成“
CiCiting from last:
对于没有父子任务的情况,请阅读 Handling Exceptions with Continuations:
“重要的是要明白两者之间没有关系 前提和延续,除了控制之外 调度。具体而言,任务抛出的异常不是 传播到其链接的延续任务。这意味着你 应该检查您运行的所有任务中的异常。该 最简单的解决方案是等待可能出错的所有任务 使用Try / Catch块“
完成并包围Wait方法
还有链接文章提供的捕获传播异常的代码示例
更新:
编辑:
我想要实现的是我想要继续执行任务 当outerTask成功完成时。我想要outerTask 传播异常从innerTask到调用者,而不必 处理innerTask。如果outerTask失败,它应该抛出 异常(在outerTask.Wait()上没有调用innerTask)。
可能您已经看过MSDN文章Task.ContinueWith Method (Func, CancellationToken, TaskContinuationOptions, TaskScheduler)中的代码示例,该示例说明了如果前提失败/成功(反之亦然,4种组合),如何阻止/遵循继续任务。但这不是父子,而是先行 - 继续任务,因此在任一方向上都没有包含或链接异常传播。
在子父任务的情况下,在子任务已经启动之后并且仅在父母失败之后(或者显然从子女中取消父母)之后是不可能的。
答案 1 :(得分:1)
要实现您想要的效果,请更改
行outerTask.Wait();
到
innerTask.Wait();
只要outertask完成,执行就会通过Wait并在内部任务处于Thread.Sleep时写入“Outer done”。
答案 2 :(得分:-1)
当第一个任务被视为“已完成”时,向任务添加延续的行为将永远不会改变。在运行所有(甚至一个特定的)延续之前,没有办法强制父母不被标记为“已完成”。