How could you explain the following behaviour:
await Task.Run(() => { }).ContinueWith(async prev =>
{
Console.WriteLine("Continue with 1 start");
await Task.Delay(1000);
Console.WriteLine("Continue with 1 end");
}).ContinueWith(prev =>
{
Console.WriteLine("Continue with 2 start");
});
Why will we get “Continue with 2 start” before “Continue with 1 end”?
ContinueWith doesn't know anything about async and await. It doesn't expect a Task result so doesn't await anything even if it gets one. await was created as a replacement for ContinueWith.
The cause of the problem is that ContinueWith(async prev => creates an implicit async void delegate. ContinueWith has no overload that expects a Task result, so the only valid delegate that can be created for ContinueWith(async prev => question's code is :
async void (prev)
{
Console.WriteLine(“Continue with 1 start”);
await Task.Delay(1000);
Console.WriteLine(“Continue with 1 end”);
}
async void methods can't be awaited. Once await Task.Delay() is encountered, the continuation completes, the delegate yields and the continuation completes. If the application exits, Continue with 1 end may never get printed. If the application is still around after 1 second, execution will continue.
If the code after the delay tries to access any objects already disposed though, an exception will be thrown.
If you check prev.Result's type, you'll see it's a System.Threading.Tasks.VoidTaskResult. ContinueWith just took the Task generated by the async/await state machine and passed it to the next continuation
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