I have been working through an article about asynchronous controller methods in ASP.NET MVC (http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx) and I think I may be missing the point.
Consider this method I wrote, which is very similar to an example from the article:
[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
WidgetPageViewModel model = new WidgetPageViewModel()
{
toAdd = new Widget()
};
model.all = await _repo.GetAllAsync(cancellationToken);
return View(model);
}
As I understand things, this is how things will unfold at runtime:
An ASP.NET thread will be created for an incoming HTTP request.
This thread will (having presumably done some necessary preliminary work) enter my Index() method above.
Execution will reach the "await" keyword and kick off a data acquisition process on another thread.
The original "ASP.NET" thread will return to the code that called my handler method, with an instance of class Task as return value.
The infrastructural code that called my handler method will continue operating on the original "ASP.NET" thread, until it reaches a point where it needs to use the actual ActionResult object (e.g. to render the page).
The caller will then access this object using the Task.Result member, which will cause it (i.e. the "ASP.NET" thread) to wait for the thread created implicitly in step #3 above.
I am not seeing what this accomplishes compared to the same thing without await / async, except for two things I perceive as trifling:
The caller thread and the worker thread created by await can operate in parallel for some period of time (the "until" part of #5 above). My hunch is that period of time is pretty small. When the infrastructure calls into a controller method, I'm thinking it generally needs the actual ActionResult of the controller call before it can do much (if anything) more.
There is some helpful new infrastructure related to timeout and cancellation of long-running asynchronous controller operations.
The purpose of adding async controller methods is supposedly to free up those ASP.NET worker threads to actually answer HTTP requests. These threads are a finite resource. Unfortunately, I'm not seeing how the pattern suggested in the article actually serves to conserve these threads. And even if it does, and somehow offloads the burden of handling the request to some non-ASP.NET thread, what does that accomplish? Are threads that happen to be capable of handling an HTTP request that much different from threads in general?
Execution will reach the "await" keyword and kick off a data acquisition process on another thread
-- Not necessarily.async
doesn't require another thread... It's a continuation. It can be accomplished by reordering instructions on the same thread.