AttachedToParent有哪些用例?

时间:2017-04-27 20:08:14

标签: c# task-parallel-library

Task.RunTaskFactory.StartNew之间的区别之一是默认情况下添加了新的DenyChildAttach选项。但AttachedToParent是出于某种原因而创建的。在什么情况下你想使用附加的子任务?

2 个答案:

答案 0 :(得分:6)

AttachedToParent的用例是当您有嵌套的dynamic task parallelism方案时。那就是:

  1. 您有一个并行执行的算法(即CPU代码,而不是I / O操作),
  2. 算法运行时,算法必须执行的任务 (也就是说,在算法启动时,它不知道需要多少任务),
  3. 在完成这些任务时存在分层或父/子关系(也就是说,"父母"在所有孩子完成之前,如果有任何孩子失败/取消,然后父母也应该失败/取消,即使它的代码没有错误)。
  4. 由于绝大多数并发问题都是基于I / O的(不是基于CPU的),并且由于绝大多数并行方案是基于数据的并行性(不是动态任务并行性),并且因为动态任务并行问题可能或者可能没有层次性,这种情况几乎从未出现过。

    不幸的是,在任务(包括异步任务)之间存在逻辑父/子关系,这导致许多开发人员错误地尝试使用AttachedToParent标记async。 1}}任务。因此,引入了DenyChildAttach标志(阻止AttachedToParent生效)。

答案 1 :(得分:2)

我能想到的唯一情况是async-await已经过时了。例如。如果您希望任务等待其子任务,您将await

var parentTask = Task.Run(async () =>
{
    await Task.Run(() => Thread.Sleep(1000));          
    Console.WriteLine("parent task completed");
});

但是在.Net 4.0中你必须Wait()。 E.g。

var parentTask = Task.Factory.StartNew(() =>
{
    Task.Factory.StartNew(() => Thread.Sleep(1000)).Wait();       
    Console.WriteLine("parent task completed");
});

与第一个示例不同,这将阻止线程直到子任务完成。通过附加任务,我们可以获得相同的行为。

var parentTask = Task.Factory.StartNew(() =>
{
    Task.Factory.StartNew(() => Thread.Sleep(1000), TaskCreationOptions.AttachedToParent)
    .ContinueWith(antecedent => Console.WriteLine("parent task completed", TaskContinuationOptions.AttachedToParent);
});