Reputation: 1062
I would like to execute three steps of work. One prepare task, one work task that is encapsulated in a method returning a task and a clean up task that requires results from the previous step. But I am not sure whether I did it the proper way with unwrapping and accessing the 'Result' property or if there is cleaner version of including the method in the execution chain.
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.ContinueWith(x => Work())
.ContinueWith(x => Console.WriteLine(x.Unwrap().Result));
Console.ReadLine();
}
private static Task<string> Work()
{
Thread.Sleep(1500);
return Task.Factory.StartNew(() => "See my results...");
}
Upvotes: 4
Views: 2293
Reputation: 99859
If you use the Rackspace Threading Library, it's easy to ensure operations are performed with the desired semantics. In addition, it handles canceled and faulted tasks in predictable ways (a daunting feat when you aren't using async
/await
, to say the least).
Select
for continuations that do not return a Task
(either a value, or void
)Then
for continuations that return a Task
or Task<T>
Example:
static void Main(string[] args)
{
Task operation = Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.Then(_ => WorkAsync())
.Select(resultTask => Console.WriteLine(resultTask.Result));
operation.Wait();
Console.ReadLine();
}
private static Task<string> WorkAsync()
{
return DelayedTask.Delay(TimeSpan.FromMilliseconds(1500))
.Select(_ => "See my results...");
}
If you still want to use the TPL directly, then the main problem (aside from cancellation and exception handling) with the original code is the placement of the call to Unwrap
. You actually would want to place it as you see in this code:
// NOTE: I WOULD NOT USE THIS CODE
// (preferring the Threading Library or async/await instead)
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.ContinueWith(x => Work()).Unwrap()
.ContinueWith(x => Console.WriteLine(x.Result));
Console.ReadLine();
}
Upvotes: 1
Reputation: 116518
You can simply have an async method that executes all the steps and returns a Task:
static async Task DoAsync()
{
Console.WriteLine("Prepare");
Console.WriteLine(await WorkAsync());
}
static void Main(string[] args)
{
DoAsync().Wait();
Console.ReadLine();
}
Upvotes: 2