2

I have an ASP.NET MVC site and a Web API. In a controller action of the MVC site I do:

public ActionResult ActionAsync()
{
    string result = MakeAsyncRequest().Result;
    return View("Index", (object)result);
}

MakeAsyncRequest() is as follows:

private async Task<string> MakeAsyncRequest()
{
    using (var client = new HttpClient())
    {
        Task<string> response = client.GetStringAsync("http://localhost:55286/api/Home");
        DoSomething();
        return await response;
    }
}

When I debug I see DoSomething() being executed (it's just a void), also the WebAPI gets called and returns a string, but then the return of MakeAsyncRequest doesn't happen and the browser stays indefinitely waiting for the server to return something.

Why is this? Something to do with the client being an ASP.NET MVC site?

Dante
  • 3,833
  • 4
  • 38
  • 55
  • 1
    Does `DoSomething()` return? What do you see in the Threads window when you pause the debugger? – CodeCaster Feb 07 '15 at 18:19
  • On a side note - I would drop the `async` function modifier and returned `response` without awaiting it. There is a small price you pay for the overhead and in this case it does not bring any benefit. – twoflower Feb 07 '15 at 18:21
  • See if you have any exceptions on the output window – MichaelLo Feb 07 '15 at 18:22
  • 4
    @twoflower in that case, HttpClient would be disposed. There is a need for *await* – EZI Feb 07 '15 at 18:23
  • 1
    The code you posted seems fine. That leaves either faulty observation (i.e. misinterpreting the result) or faulty code elsewhere. Either way, the question is incomplete. See http://stackoverflow.com/help/mcve – Peter Duniho Feb 07 '15 at 18:28
  • @PeterDuniho I added more details to the question. Better now? – Dante Feb 07 '15 at 18:41
  • How do you know that "the WebAPI...returns a string"? I.e. the code you added (still not complete, btw) will simply wait until the operation completes (so why use `async` here?). If the server never responds, the operation will never complete and the code will hang. There's really not enough context to know what might be going wrong here. – Peter Duniho Feb 07 '15 at 18:45
  • I know the web api was returning a string because I debugged it. I saw the web api returning the string and then nothing, it was hanging. Or as I now understand from the answer to the question, it was in a deadlock state. Thanks for the answers. – Dante Feb 07 '15 at 19:00

1 Answers1

6

.Result

That's a classic ASP.NET deadlock. Don't block. Or, don't use async/await but your case seems like a good fit. Make the action async as well.

Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
  • ah...so, ASP.NET uses a synchronization context? good to know! (I know...probably almost everyone actually doing ASP.NET already knows this, but I didn't :p) – Peter Duniho Feb 07 '15 at 18:47
  • @PeterDuniho - I believe *async/await* uses a synchronization context. It's not unique to ASP.NET. I could be wrong though... – Tim Feb 07 '15 at 18:50
  • This did the trick. Thank you for the response and for the link. Cheers! – Dante Feb 07 '15 at 18:58
  • 1
    @Tim: `await` will use the context if one is present. But one is present only in specific scenarios; otherwise, continuations are executed on a random thread pool thread. The deadlock can happen only where there is a context, which forces the continuation to wait for the context's thread to be available; if the caller of the code is blocking that context thread waiting on the async operation to complete, then the async operation can't complete because it needs the context thread to do so. – Peter Duniho Feb 07 '15 at 19:03
  • @PeterDuniho - Got it. Thanks for the explanation - we're just starting to use async/await at work, so this will be good information to keep in mind. – Tim Feb 07 '15 at 19:18