我正在尝试将Task.ContinueWithTaskContinuationOptions.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)。

最佳答案

您的代码中没有父子任务。
您可能要检查什么是内部任务或子任务,它可以有两种类型:

  • detached child task or nested task,即与另一个任务的委托(delegate)一起创建的并行任务,而没有与任务创建者
  • 的连接
  • attached child task or simply child task,在这种情况下,如果子任务引发了异常,而该异常无法处理,则由父级捕获并重新抛出

    更新



    最后引用:
  • “父任务只有在其所有子任务正常或异常完成后才能完成执行。父任务实际上是对其所有子任务执行Wait命令。
  • 如果子任务引发了异常,否则将无法处理该异常,父任务会捕获该异常并重新抛出该异常。许多子任务有可能引发异常。所有这些都将与父级直接在单个AggregateException中抛出的任何未处理的异常合并。”

  • 对于您的情况(其中没有父子任务),请阅读Handling Exceptions with Continuations:



    链接文章提供的捕获传播异常的代码示例

    更新:



    可能您已经从MSDN文章Task.ContinueWith Method (Func, CancellationToken, TaskContinuationOptions, TaskScheduler)中看到了代码示例,该代码示例说明了如果先行失败/成功(反之亦然,有4种组合),则如何防止/遵循继续任务。但是,这不是父子任务,而是先行继续任务,因此,没有任何遏制或链接可以在任一方向上传播异常。

    对于子代任务,不可能在启动子任务之后且仅在父任务失败(或显然从子任务中取消父任务)之后阻止子任务。

    10-08 14:02