سؤال

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. I want to then return a future with the value for the caller to add a continuation on. 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?

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.

Edit: Or, as Alex points out, use

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

and read the result from 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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top