the controller is marked async but the implementation uses synchronous HttpWebRequest calls, in that my controller is awaiting Task.Run( sync web request )
Think about what is happening in the request. The request comes in and ASP.NET takes a thread pool thread to handle the request. The controller action queues the work to the thread pool (taking up another thread), and then await
s that work, freeing up the original request thread. You haven't gained anything by using await
because there's still a thread pool thread blocking on the web request.
For this reason, you should almost never use Task.Run
(or any other method that queues work to the thread pool) on ASP.NET.
Is this suitable or should i use the Begin/End methods of HttpWebRequest too. This seems like overkill as it would be asyncing an already async operation
It's not really asynchronous right now; there's still a thread being blocked. I call this "queue blocking work to a thread pool thread and then await it" technique fake asynchrony.
The appropriate fix is to use HttpClient
, which was designed for asynchronous use; or, you could use TaskFactory<T>.FromAsync
to wrap the Begin
/End
methods into an awaitable task.
The thing i dont understand though is if i use await HttpClient.SendAsync then somewhere something must be blocking waiting for a response
No, there doesn't have to be something blocking somewhere. As I describe on my blog, in a truly asynchronous scenario (i.e., not fake-asynchrony), there is no thread.