10

我开始在 C# 中使用任务。我正在尝试执行此代码。

    private static void CreateSubtask() {

        Task<Int32[]> parent = Task.Run(() =>
        {
            var results = new Int32[3];
            new Task(() => results[0] = 0,
                TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[1] = 1,
                TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[2] = 2,
                TaskCreationOptions.AttachedToParent).Start();
            return results;
        });
        var finalTask = parent.ContinueWith(
           parentTask =>
           {
               foreach (int i in parentTask.Result)
                   Console.WriteLine(i);
           });
        finalTask.Wait();
    }

finalTask仅在父级完成后运行,Task并且Task在所有三个子级都完成时父级完成。您可以使用它来创建非常复杂Task的层次结构,这些层次结构将完成您指定的所有步骤。

我从执行中得到的是三行内容:

0
0
0

我原以为他们会

0
1
2

我对吗?

4

3 回答 3

8

与父任务一起使用Task.Run会抑制AttachedToParent对子任务的影响:

Task.Run 与 Task.Factory.StartNew由 Stephen Toub 编写。

改为使用Task.Factory.StartNew

于 2013-10-07T13:04:10.077 回答
5

问题是您的parent任务在完成启动其他三个任务时完成,而不是在其他三个任务完成时完成

相反,您可以使用它Task.WhenAll来创建将在所有其他任务本身完成时完成的任务。

另一个使您的程序更符合惯用任务代码的更改是让每个内部任务返回它们自己的值,而不是改变某些共享状态,这仅仅是因为在多线程环境中处理共享状态可能更难推理。

var parent = Task.WhenAll(Task.Run(() => 0),
    Task.Run(() => 1),
    Task.Run(() => 2));
var finalTask = parent.ContinueWith(t =>
    {
        foreach (int n in t.Result)
            Console.WriteLine(n);
    });
finalTask.Wait();
于 2013-10-07T16:42:19.803 回答
1

您只是开始您的三个子任务,而不是等待它们完成。像这样调整它,例如:

            var task1 = new Task(() => results[0] = 0,
                TaskCreationOptions.AttachedToParent);
            var task2 = new Task(() => results[1] = 1,
                TaskCreationOptions.AttachedToParent);
            var task3 = new Task(() => results[2] = 2,
                TaskCreationOptions.AttachedToParent);

            task1.Start();
            task2.Start();
            task3.Start();

            task1.Wait();
            task2.Wait();
            task3.Wait();

另请注意,使用您当前的代码,仍然可以显示0 1 2(不是1 2 3顺便说一句),因为无法确定子任务何时运行/完成。这也可能取决于您的构建配置(调试/发布)。

于 2013-10-07T13:03:53.980 回答