Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConfigureAwait(false) still deadlocks

I've been reading up a bit on async/await and was trying to reproduce a deadlock scenario in windows forms by calling WebClient.DownloadStringTaskAsync on the UI thread and then calling task.Result on the UI thread while the task was executing. This resulted in a deadlock.

Then I tried to address the issue by calling ConfigureAwait(false) on the returned task, but to my surprise that still caused a deadlock. My understanding is that it should execute the continuation of the method on a different thread and hence there should be no deadlock. What am I missing?

I know how to get around the issue but thought ConfigureAwait(false) would fix it as well.

Here is the code, I am using NET 4.5

    private async void button1_Click(object sender, EventArgs e)
    {
        // Deadlocks!
        Task<string> task = DownloadAsync();
        textBox1.Text = task.Result;

        // Works
        //textBox1.Text = await DownloadAsync();
    }

    private static async Task<string> DownloadAsync()
    {
        var client = new WebClient();

        string result = await client.DownloadStringTaskAsync("http://www.rpmglobal.com").ConfigureAwait(false);          

        return result;
    }
like image 917
NeddySpaghetti Avatar asked Aug 30 '13 03:08

NeddySpaghetti


People also ask

How to avoid deadlock using configureawait () method?

Using ConfigureAwait(false) to avoid deadlocks is a dangerous practice. You would have to use ConfigureAwait(false) for every await in the transitive closure of all methods called by the blocking code, including all third- and second-party code. Using ConfigureAwait(false) to avoid deadlock is at best just a hack).

When to use configureawait (false)?

If some user code (or other library code your app is using) sets a custom context and calls your code, or invokes your code in a Task scheduled to a custom TaskScheduler, then even in ASP.NET Core your awaits may see a non-default context or scheduler that would lead you to want to use ConfigureAwait(false).

How to avoid deadlock when async await is blocked?

The deadlock occurs because the await is waiting for the UI thread to be free and the UI thread is blocked on the async method to complete. ConfigureAwait (false) avoids the deadlock by allowing the await to resume on a thread pool thread instead of the UI thread.

How do you avoid deadlock in Java?

Avoiding deadlocks. Consider a library method that uses await on the result of some network download. You invoke this method and synchronously block waiting for it to complete, such as by using .Wait() or .Result or .GetAwaiter().GetResult() off of the returned Task object.


1 Answers

WebClient will still cause this deadlock because DownloadStringTaskAsync is just a wrapper around the EAP methods, which always raise their event in the original context. There's no way to turn this off.

Try using HttpClient (or something simple like Task.Delay) to see the difference.

like image 115
Stephen Cleary Avatar answered Oct 18 '22 06:10

Stephen Cleary