The following code will freeze forever.
public async Task DoSomethingAsync()
{
await Task.Delay(2000);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DoSomethingAsync().Wait();
// Task.Delay(2000).Wait();
}
If I switch the call to DoSomethingAsync
with the commented out code, it behaves as expected. I suspect that somehow the nested awaits are causing a deadlock, but I'm not sure why, or how to fix it.
If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call. By default, this message is a warning.
The Delay method is typically used to delay the operation of all or part of a task for a specified time interval. Most commonly, the time delay is introduced: At the beginning of the task, as the following example shows.
Delay(1000) doesn't block the thread, unlike Task. Delay(1000).
Task. Delay does not create new Thread, but still may be heavy, and no guaranties on order of execution or being precise about deadlines.
Assuming Button_Click
runs in the GUI
thread you have a deadlock on your hands.
When you use Wait
on a task you are synchronously blocking the thread until the task ends, but the task will never end because the continuation (the completion of Task.Delay(2000);
) must run on the GUI thread as well (which is blocked on Wait).
You have several solutions. Either use ConfigureAwait(false)
to not capture the GUI thread's SynchronizationContext:
public async Task DoSomethingAsync()
{
await Task.Delay(2000).ConfigureAwait(false);
}
Or (which I recommend) use an async void
event handler (which is the only appropriate place for an async void
method):
private async void Button_Click(object sender, RoutedEventArgs e)
{
await DoSomethingAsync();
}
public async Task DoSomethingAsync()
{
await Task.Delay(2000);
}
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