I'm trying to play a bit with C#'s async/await/continuewith.
My goal is to have to have 2 tasks which are running in parallel, though which task is executing a sequence of action in order.
To do that, I planned to have a List<Task>
that represent the 2 (or more) tasks running in parallel, and to use ContinueWith
on each of the Task
My problem is that the callback in continue with seems not to be executed while the await taskList
has already returned.
In order to summarize, here's a sample to illustrate what I'm expecting to happen:
class Program
{
static public async Task Test()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static void Main(string[] args)
{
Test().ContinueWith(
async (task) =>
{
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
},
TaskContinuationOptions.AttachedToParent).Wait();
Console.WriteLine("Done with test");
}
}
The expected output would be
Enter Test
Leave Test
Enter callback
Leave callback
Done with test
However, the output is
Enter Test
Leave Test
Enter callback
Done with test
Is there a way to make the Task on which ContinueWith
is called wait for the provided function to complete before being considered as done? ie. .Wait will wait for both tasks to be completed, the original one, and the one which is returned by ContinueWith
When chaining multiple tasks using the ContinueWith
method, your return type will be Task<T>
whereas T
is the return type of the delegate/method passed to ContinueWith
.
As the return type of an async delegate is a Task
, you will end up with a Task<Task>
and end up waiting for the async delegate to return you the Task
which is done after the first await
.
In order to correct this behaviour, you need to use the returned Task
, embedded in your Task<Task>
. Use the Unwrap
extension method to extract it.
When you're doing async
programming, you should strive to replace ContinueWith
with await
, as such:
class Program
{
static public async Task Test()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static async Task MainAsync()
{
await Test();
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
}
static void Main(string[] args)
{
MainAsync().Wait();
Console.WriteLine("Done with test");
}
}
The code using await
is much cleaner and easier to maintain.
Also, you should not use parent/child tasks with async
tasks (e.g., AttachedToParent
). They were not designed to work together.
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