I've been seeing some conflicting information on the subject, and I would like to achieve some clarity here.
Originally, you would have Web Api actions such as:
Model Action();
HttpResponseMessage Action();
Then, with the addition of TPL enhancements to Web Api, you could have
Task<Model> Action();
Task<HttpResponseMessage> Action();
And supposedly, ASP.NET would be smart enough to handle those by waiting for the task to finish, and by releasing the thread that picked up the request in the mean time.
Beautiful! Everything was simple in the world. But now, with Web API 2, there is a the addition of IHttpActionResult
, a third case, which provides the Task<HttpResponseMessage> ExecuteAsync()
method.
First off, if you inspect implementations of IHttpActionResult
, you see that every ExecuteAsync
actually just returns Task.FromResult
(not async at all, and does not seem like it would give any performance gain over synchronously returning HttpResponseMessage
). Second, I see people recommending to use Task<IHttpActionResult>
, which seems entirely redundant. I even see a handful of people suggesting that you combine these approaches and return Task.Factory.StartNew(..)
from your action, which seems kind of absurd.
So what is the correct way to use IHttpActionResult
asynchronously? Do you simply implement your own, and do asynchronous operations there†, or do you return Task<IHttpActionResult>
, make your method async
, and await on IO-bound operations before calling to return Ok()
(or equivalent)?
To be clear, I do obviously understand that simply going from IHttpActionResult Action();
to Task<IHttpActionResult> Action();
without changing the method body will not help in any way. It is the intent of the ExecuteAsync
that is a puzzle.