简体   繁体   English

TPL中的任务排序

[英]Ordering of tasks in TPL

If I have the following code 如果我有以下代码

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        static Task<int> GetSuperLargeNumber()
        {
            var main = Task.Factory.StartNew(() =>
                                                 {
                                                     Thread.Sleep(1000);
                                                     return 100;
                                                 });
            var second = main.ContinueWith(x => Console.WriteLine("Second: " + x.Result), TaskContinuationOptions.AttachedToParent);
            var third = main.ContinueWith(x => Console.WriteLine("Third: " + x.Result), TaskContinuationOptions.AttachedToParent);

            return main.ContinueWith(x  =>
                                             {
                                                 Task.WaitAll(second, third);
                                                 return x.Result;
                                             });
        }

        static void Main(string[] args)
        {
            GetSuperLargeNumber().ContinueWith(x => Console.WriteLine("Complete"));

            Console.ReadKey();
        }
    }
}

I want main to start first, then 2 dependencies can start after that which in parallel which are first and second. 我希望main首先启动,然后2个依赖项可以在其后并行启动,它们分别是第一和第二。 I want to then return a future with the value for the caller to add a continuation on. 然后,我想返回一个带有值的future,以便调用者在其上添加延续。 However i want to ensure second and third have run first. 但是,我想确保第二和第三个先运行。 Is the code below the best way to achieve this? 下面的代码是实现此目标的最佳方法吗? Seems kinda clunky 似乎有点笨拙

I'm not too familiar with TPL, but isn't this what ContinueWhenAll is for? 我对TPL不太熟悉,但这不是ContinueWhenAll目的吗?

static Task<int> GetSuperLargeNumber()
{
    var main = Task.Factory.StartNew(() =>
                                         {
                                             Thread.Sleep(1000);
                                             return 100;
                                         });
    var second = main.ContinueWith(
        x => Console.WriteLine("Second: " + x.Result),
        TaskContinuationOptions.AttachedToParent);
    var third = main.ContinueWith(
        x => Console.WriteLine("Third: " + x.Result),
        TaskContinuationOptions.AttachedToParent);

    return Task.Factory.ContinueWhenAll(
        new[] { second, third },
        (twotasks) => /* not sure how to get the original result here */);
    }

I don't know how to get main 's result from the completed second and third (contained in twotasks ), but maybe you can modify them to pass through the result. 我不知道如何从完成的secondthird (包含在twotasks )获取main的结果,但是也许您可以修改它们以传递结果。

Edit: Or, as Alex points out, use 编辑:或者,正如亚历克斯指出,使用

Task.Factory.ContinueWhenAll(new[] { main, second, third }, (threetasks) => ...

and read the result from threetasks[0] . 并从threetasks[0]读取结果。

This would suffice: 这样就足够了:

static Task<int> GetSuperLargeNumber()
{
    var main = Task.Factory.StartNew<int>(() =>
    {
        Thread.Sleep(1000);
        return 100;
    });
    var second = main.ContinueWith(x => Console.WriteLine("Second: " + x.Result), TaskContinuationOptions.AttachedToParent);
    var third = main.ContinueWith(x => Console.WriteLine("Third: " + x.Result), TaskContinuationOptions.AttachedToParent);

    Task.WaitAll(second, third);

    return main;
}

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

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