25

I am trying to use Async and Await when making a web request and am finding that it never gets past the await line. I am doing this from a Metro app, but I also verified the problem in a winforms app.

public async Task<string> DoSomething()
{
    string url = "http://imgur.com/gallery/VcBfl.json";
    HttpWebRequest request = HttpWebRequest.CreateHttp(url);

    var ws = await request.GetResponseAsync();

    return ws.ResponseUri.ToString(); ;
}

If I don't use await and instead perform a synchronous wait, it works, but I need this to run asynchronously.

What am I missing in this code that is causing the await to never return?

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
John Koerner
  • 37,428
  • 8
  • 84
  • 134

1 Answers1

39

I suspect that further up your call stack, you're either calling Wait or Result on the returned Task. This will cause a deadlock, as I describe on my blog.

Follow these best practices to avoid the deadlock:

  1. Don't block on async code; use async all the way down.
  2. In your "library" methods, use ConfigureAwait(false).
weston
  • 54,145
  • 21
  • 145
  • 203
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • 3
    Thank you. That was exactly it. Thanks for the link, it is very helpful. – John Koerner Oct 03 '12 at 04:35
  • @Stephen, thanks for the blog posts! Clarifying question: if I use `.ConfigureAwait(false)` in my lib (basically a WebClient), can I then use `.Result` when calling it? It seems to work, but I don't know what will happen when I set it loose in the wild. – Brad Sep 04 '14 at 16:54
  • @Brad: Yes, as long as the async method you're calling does the same thing. However, it's not a best practice to use `Result`; there are always better options. – Stephen Cleary Sep 04 '14 at 16:58
  • @Stephen, the async method I'm calling returns a Task and does NOT call result. The code in question is a custom wrapper for calling an internal API and the only part I want to make async in the actual GET/POST methods (GetRequestStreamAsync, GetResponseAsync, etc). How do I keep this async without making every method between this and the controller action async and returning a Task? I'd like for the lib to take care of the async nature and the consumer to remain agnostic. – Brad Sep 04 '14 at 17:13
  • 2
    @Brad: That's not possible, due to the nature of asynchronous code. It's best to use async all the way. – Stephen Cleary Sep 04 '14 at 18:31