Use an async callback with Task.ContinueWith
Solution 1:
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.
Solution 2:
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.
Solution 3:
I'd like to add my answer to complement the answer which has already been accepted. Depending on what you're trying to do, often it's possible to avoid the added complexity of async delegates and wrapped tasks. For example, your code could be re-factored like this:
class Program
{
static async Task Test1()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static async Task Test2()
{
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
}
static async Task Test()
{
await Test1(); // could do .ConfigureAwait(false) if continuation context doesn't matter
await Test2();
}
static void Main(string[] args)
{
Test().Wait();
Console.WriteLine("Done with test");
}
}