简体   繁体   English

C#中的任务示例

[英]Task example in C#

I am starting using Tasks in C#. 我开始在C#中使用Tasks。 I am trying to execute this code. 我正在尝试执行此代码。

    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();
    }

The finalTask runs only after the parent Task is finished, and the parent Task finishes when all three children are finished. finalTask​​仅在父Task完成后运行,并且父Task完成所有三个子节点完成后。 You can use this to create quite complex Task hierarchies that will go through all the steps you specified. 您可以使用它来创建非常复杂的Task层次结构,它将完成您指定的所有步骤。

What I got from the execution instead is three lines saying: 我从执行中得到的是三行说:

0 0 0 0 0 0

I was expecting them to be 我期待着他们

0 1 2 0 1 2

Am i right? 我对吗?

Using Task.Run with the parent task suppresses the effect of AttachedToParent on teh child task: http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx Task.Run与父任务一起使用Task.Run抑制AttachedToParent对子任务的影响: http//blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

Use Task.Factory.StartNew instead. 请改用Task.Factory.StartNew

The problem is that your parent task completes when it finishes starting the other three tasks, not when the other three tasks are finished . 问题是,你的parent ,当它完成启动其他三项任务,而不是在其他三个任务完成后任务完成。

Instead you can use Task.WhenAll to create a task that will be completed when all of the other tasks are themselves completed. 相反,您可以使用Task.WhenAll创建一个任务,该任务将在所有其他任务本身完成时完成。

Another change to make your program more idiomatic task code is to have each inner task return their own value, rather than mutating some shared state, simply because dealing with shared state can be harder to reason about in a multithreaded environment. 使程序更具惯用性任务代码的另一个变化是让每个内部任务返回自己的值,而不是改变某些共享状态,这仅仅是因为在多线程环境中处理共享状态可能更难以推理。

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();

You are only starting your three sub tasks, but not waiting for them to finish. 你只是开始你的三个子任务,但不等待它们完成。 Adapt it like this, for example: 像这样适应它,例如:

            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();

Also note that with your current code, it is still possible to show 0 1 2 (not 1 2 3 by the way), as it is not determined when the subtasks are running / finishing. 另请注意,使用当前代码时,仍然可以显示0 1 2 (顺便说一下不是1 2 3 ),因为在子任务运行/完成时无法确定。 This might also be dependent on your build configuration (debug / release). 这可能还取决于您的构建配置(调试/发布)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM