嵌套任务和子任务有什么区别?

7

我想了解“嵌套任务”和“子任务”的区别。

var outerTask = Task.Factory.StartNew( () => 
{
    var nestedTask = Task.Factory.StartNew( () => 
    {
         Console.WriteLine("Inside nestedTask");
    });
});


A "child task" looks like this:

var parentTask = Task.Factory.StartNew( () => 
{
    var childTask = Task.Factory.StartNew( () => 
    {
         Console.WriteLine("Inside childTask");
    },               TaskCreationOptions.AttachedToParent );
});

这里我附上了代码。

似乎当我们启动任何嵌套任务时,外部任务可能会在内部任务之前完成,但是在子任务的情况下,始终会先完成子任务再完成父任务。我不确定我是否正确。因此,如果有人能给我指导什么时候使用嵌套任务和子任务,并提供一些示例场景,那将非常有帮助。谢谢。

3个回答

15

我个人认为,最好的解释可以在Stephen Toub的博客帖子中找到:

被创建的Task将向父级Task注册为一个子任务,导致两个额外的行为:只有当所有子任务完成后,父级Task才会转换为已完成状态,并且故障的子任务的任何异常都将向上传播到父级Task(除非父级Task在完成之前观察到这些异常)。


4
+1 对于一个实际说明行为差异的答案(并链接到详细阐述和演示的博客文章)。比其他答案中模糊的“与父级密切同步”短语更有用。 - TypeIA

10

微软很好地解释了这个问题。

嵌套任务只是在另一个任务的用户委托中创建的任务实例。附加到父级任务的子任务是一种嵌套任务。任务可以创建任意数量的子任务和/或嵌套任务,仅受系统资源限制。以下示例显示了创建一个简单嵌套任务的父任务。

...

关于子任务 vs. 嵌套任务最重要的一点是,嵌套任务基本上与父任务或外部任务相互独立,而附加的子任务与父任务非常密切同步。

http://msdn.microsoft.com/zh-cn/library/vstudio/dd997417%28v=vs.100%29.aspx


我很高兴你添加了第二部分,因为第一部分基本上描述了提问者的代码。 - Ondrej Janacek
@OndrejJanacek 我认为只提供官方文档的链接就足够了。我只插入引用以防止抱怨 :D - Gusdor
1
仅发布链接是懒惰的做法 :) 从中找出重要部分绝对是一种好方法。 - Ondrej Janacek
1
@OndrejJanacek 这篇文章专门针对这个问题。所有内容都是相关的。确实是一个罕见的情况!我倾向于同意,提取主要信息可以给出简明扼要的答案,并使我的输入看起来更专业,标记也更加漂亮 ;) - Gusdor

1
简单来说,如果一个子任务没有附加到父任务上,那么该任务将失败?然后父任务的状态仍将是"RanToCompletion"。
var parentTask = Task.Factory.StartNew(() =>
{
    var childTask = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Inside childTask");
    }, TaskCreationOptions.AttachedToParent);

    var childTask2 = Task.Factory.StartNew(() =>
    {
        Thread.Sleep(1000 * 3);
        throw new Exception("Bomb2");
        Console.WriteLine("Inside childTask2");
    }, **TaskCreationOptions.None**);   // If not AttachedToParent, parentTask.Status == RanToCompletion
}).ContinueWith(t =>
{
    Console.WriteLine(t.Status);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接