As I read the MSDN article Using Asynchronous Methods in ASP.NET MVC 4, I draw the conclusion that I should always use async await for I/O-bound operations.
Consider the following code, where movieManager exposes the async methods of an ORM like Entity Framework.
public class MovieController : Controller
{
// fields and constructors
public async Task<ActionResult> Index()
{
var movies = await movieManager.listAsync();
return View(movies);
}
public async Task<ActionResult> Details(int id)
{
var movie = await movieManager.FindAsync(id);
return View(movie);
}
}
I know these are a lot of questions, but literature on this topic has conflicting conclusions. Some say you should always use async for I/O dependent Tasks, others say you shouldn't use async in ASP.NET applications at all.
Sometimes the method does not need to be async, but return a Task<T> and let the other side handle it as appropriate. If the last sentence of your code is a return await you may actually consider refactoring it so that the return type of the method is Task<T> (instead of async T).
No, you should not. Making everything async hurts reading, writing and understanding your code, even if only a little. It could also hurt the performance of your code, especially if you really made every single method (does that include properties?) async .
Asynchronous calls are most useful when facing relatively infrequent large, expensive operations that could tie up response threads which could otherwise be servicing requests while the originator waits. For quick, common operations, async can slow things down.
Asynchronous actions are best when your method is I/O, network-bound, or long-running and parallelizable. Another benefit of an asynchronous action is that it can be more easily canceled by the user than a synchronous request.
Will this always give me better scalability and/or performance?
It may. If you only have a single database server as your backend, then your database could be your scalability bottleneck, and in that case scaling your web server won't have any effect in the wider scope of your service as a whole.
How can I measure this?
With load testing. If you want a simple proof-of-concept, you can check out this gist of mine.
Why isn't this used in the "real world" a lot?
It is. Asynchronous request handlers before .NET 4.5 were quite painful to write, and a lot of companies just threw more hardware at the problem instead. Now that .NET 4.5 and async
/await
are gaining a lot of momentum, asynchronous request handling will continue to be much more common.
How about context synchronization?
It's handled for you by ASP.NET. I have an async
intro on my blog that explains how await
will capture the current SynchronizationContext
when you await
a task. In this case it's an AspNetSynchronizationContext
that represents the request, so things like HttpContext.Current
, culture, etc. all get preserved across await
points automatically.
Is it that bad, that I shouldn't use async I/O in ASP.NET MVC?
As a general rule, if you're on .NET 4.5, you should use async
to handle any request that requires I/O. If the request is simple (i.e., does not hit a database or call another service), then just keep it synchronous.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With