C# C语言中的任务示例#

C# C语言中的任务示例#,c#,parallel-processing,C#,Parallel Processing,我开始使用C#中的任务。 我正在尝试执行此代码 private static void CreateSubtask() { Task<Int32[]> parent = Task.Run(() => { var results = new Int32[3]; new Task(() => results[0] = 0, TaskCreationOpti

我开始使用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();
    }
private static void CreateSubtask(){
任务父级=任务。运行(()=>
{
var结果=新的Int32[3];
新任务(()=>结果[0]=0,
TaskCreationOptions.AttachedToParent.Start();
新任务(()=>结果[1]=1,
TaskCreationOptions.AttachedToParent.Start();
新任务(()=>结果[2]=2,
TaskCreationOptions.AttachedToParent.Start();
返回结果;
});
var finalTask=parent.ContinueWith(
父任务=>
{
foreach(parentTask.Result中的int i)
控制台写入线(i);
});
finalTask.Wait();
}
finalTask仅在父任务完成后运行,并且父任务在所有三个子任务完成时完成。您可以使用它来创建相当复杂的任务层次结构,这些任务层次结构将经历您指定的所有步骤

我从死刑中得到的是三句话:

0 0 0

我期待着他们的到来

0 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
),因为它不确定子任务何时运行/完成。这也可能取决于您的生成配置(调试/发布)。

使用
任务。与父任务一起运行
会抑制
附加到子任务上的影响:


改用
Task.Factory.StartNew

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

相反,您可以使用
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();

我不熟悉Task Parallel Library,但我猜您在Task
parent
中创建的三个任务在您阅读
parent
的结果时尚未运行。您似乎在等待
parent
完成,但不是等待在inde
parent
中创建的三个任务。我运行了您的代码,得到了0 1 2,这是我所期望的
AttachedToParent
通常会使父级等待其子级。问题是,为什么它不在这里呢?从链接文章中可以看出:“[Task.Run]应该被认为是使用Task.Factory.StartNew的一种快速方法”。在本文的后续部分,将详细说明传递给基础StartNew的参数包括TaskCreationOptions.denychildatach。