I expect deadlock occurs on below code:
static async Task<int> DelayAndReturnAsync(int val)
{
await Task.Delay(TimeSpan.FromSeconds(val));
return val;
}
static async Task<int> ProcessTaskAsync()
{
var taskA = await DelayAndReturnAsync(3);
int num = taskA++;
return num;
}
static void Main(string[] arg)
{
var testTask = ProcessTaskAsync();
testTask.Wait();
Console.WriteLine("Done");
}
As the main thread(current context) is put on wait after calling ProcessTaskAsync()
and being blocked on teskTask.Wait()
, it cannot go back to the method and continue the rest of the code when DelayAndReturnAsync()
completed.The main thread will wait for ProcessTaskAsync
to complete while ProcessTaskAsync
is waiting for it(the original context) to continue with the rest of the code. Thus a deadlock.
Please let me know if there is anything wrong with my understanding.
I was originally trying to replicate a deadlock and test the solution which uses ConfigureAwait(false)
method on ProcessTaskAsync
. e.g. ProcessTaslAsync.ConfigureAwait(false)
.
That deadlock can only happen in the presence of a SynchronizationContext
which isn't present by default in console apps. Since there's no SynchronizationContext
to begin with it's as if every await
implicitly adds ConfigureAwait(false)
.
You can try it in a UI or asp.net application or even better add a SynchronizationContext
to your test with Stephen Cleary's AsyncContext
:
"The
AsyncContext
type provides a context for executing asynchronous operations. The await keyword requires a context to return back to; for most programs, this is a UI context, and you don't have to worry about it. ASP.NET also provides a proper context and you don't have to use your own.However, Console applications and Win32 services do not have a suitable context, and
AsyncContext
orAsyncContextThread
could be used in those situations."
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