Task.Run
和TaskFactory.StartNew
之间的区别之一是默认情况下添加了新的DenyChildAttach
选项。但AttachedToParent
是出于某种原因而创建的。在什么情况下你想使用附加的子任务?
答案 0 :(得分:6)
AttachedToParent
的用例是当您有嵌套的dynamic task parallelism方案时。那就是:
由于绝大多数并发问题都是基于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);
});