Take a look at this code:
private async Task InnerTask(bool outerTaskResult)
{
Console.WriteLine("2");
await Task.Factory.StartNew(() => Thread.Sleep(10000));
Console.WriteLine("3");
}
private async void Button2_Click(object sender, RoutedEventArgs e)
{
var task = Task.FromResult(false);
Task<Task> aggregatedTask = task.ContinueWith(task1 => InnerTask(task1.Result));
Console.WriteLine("1");
await aggregatedTask;
Console.WriteLine("4");
}
The desired output is:
1
2
3
4
But I get:
1
2
4
3
This probably has something to do with InnerTask being executed on a different thread.
I'm using ContinueWith because the tasks in the original code are dynamically created and queued this way.
Using .Wait() method (see below) works, but I think it's a bad idea, as the method is blocking.
task.ContinueWith(task1 => InnerTask(task1.Result).Wait())
What's the correct approach here?
The Task. WaitAll() method in C# is used to wait for the completion of all the objects of the Task class. The Task class represents an asynchronous task in C#. We can start threads with the Task class and wait for the threads to finish with the Task.
await hides all this complexity from you, and it allows you to await the same task in ten different places (very useful for e.g. asynchronous lazy initialization). can I be assured that the method pointed by task wont be executed twice even if the task is running or ran already ? @BilalFazlani Yes, you can.
A continuation task (also known just as a continuation) is an asynchronous task that's invoked by another task, known as the antecedent, when the antecedent finishes.
await Task. Delay(1000) doesn't block the thread, unlike Task. Delay(1000).
You can use TaskExtensions.Unwrap()
(which is an extension method on Task<Task>
) to unwrap the outter task and retrieve the inner one:
private async void Button2_Click(object sender, RoutedEventArgs e)
{
var task = Task.FromResult(false);
Task aggregatedTask = task.ContinueWith(task1 => InnerTask(task1.Result)).Unwrap();
Console.WriteLine("1");
await aggregatedTask;
Console.WriteLine("4");
}
Note that to simplify this entire thing, instead of ContinueWith
style continuation you can await
on your tasks:
private async void Button2_Click(object sender, RoutedEventArgs e)
{
var task = Task.FromResult(false);
Console.WriteLine("1");
var result = await task;
await InnerTask(result);
Console.WriteLine("4");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With