Tag Archives: async

Asynchronously deadlocked, or Do not wrap async methods into sync wrappers (HttpClient.GetAsync not returning)

DeadlockI’m currently working on a new project which for which I decided to try out some new libraries and on the way familiarize myself a little bit better with new C# async language extensions. Even though I’ve read about the extensions, and have basic understanding of .NET task parallel libraries (which are kind of base for async extensions), it didn’t take me long to get stuck.

Application consists of ASP.NET WebAPI application which provides some data to clients, WPF client application utilizing Caliburn.Micro for presentation and some auxiliary libraries. WPF application attempts to retrieve data form WebAPI client in order to authenticate application user.  This is done using HttpClient class and WebAPI extensions of it.

While sketching out application code, things worked fine. After trying to separate code into methods, threads started getting dead locked and UI started freezing. Nothing notable has changed. Code looked something like this:

private void btnShowFoo_Click(object sender, RoutedEventArgs e)
{
    string foo = PrettyFoo();
    ShowFoo(foo);
}

public string PrettyFoo()
{
    var foo = GetFooAsync().Result;
    GiveMakeOver(foo);
    return foo;
}

public static async Task<string> GetFooAsync()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("http://www.msdn.com");
    //    ...
}

Problem is not very easy to spot. btnShowFoo_Click calls PrettyFoo to get value which needs to be displayed. PrettyFoo in turn calls asynchronous method and waits for it result synchronously, which it then returns. This looked ok to me. It wasn’t new to me that compiled async code actually generates helper classes, callbacks and other helper things to prettify threading, but still I let this go without thinking what it actually does.

btnShowFoo_Click is executed in UI thread. When it calls PrettyFoo it blocks until called method completes and returns result. PrettyFoo asynchronously calls GetFooAsync and yields control of the thread. This is where things get interesting. Before UI thread is yielded, PrettyFoo creates continuation that will execute on UI thread, which will return result to btnShowFoo_Click. However, since btnShowFoo_Click is already blocked on UI thread, PrettyFoo‘s code which is supposed to return result waits for UI thread to be released forever. This causes UI to hang.

Since I probably didn’t do a good job explaining the problem, I suggest you read this super awesome article by Stephen Toub (Should I expose synchronous wrappers for asynchronous methods?).

Solution? It’s kind of obvious now, isn’t it? Do not wrap async methods into synchronous wrappers before thinking thrice. While we’re at that, don’t wrap sync methods into async wrappers. Stephen Toub has another excellent article on this too. If you’re thinking about using async C# language extensions, it’s a good idea to spend time to read and understand them. Seems I didn’t really understand them the first time.

How should my fixed code look like? Something like this:

private async void btnShowFoo_Click(object sender, RoutedEventArgs e)
{
    string foo = await PrettyFoo();
    ShowFoo(foo);
}

public async Task<string> PrettyFoo()
{
    var foo = await GetFooAsync();
    GiveMakeOver(foo);
    return foo;
}

public static async Task<string> GetFooAsync()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("http://www.msdn.com");
    //    ...
}