Reputation: 951
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
Upvotes: 0
Views: 1317
Reputation: 50114
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]
.
Upvotes: 3
Reputation: 32561
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;
}
Upvotes: 0