Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should all my actions using IO be async?

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);
    }
}
  1. Will this always give me better scalability and/or performance?
    • How can I measure this?
  2. Why isn't this used in the "real world"?
  3. How about context synchronization?
    • Is it that bad, that I shouldn't use async I/O in ASP.NET MVC?

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.

like image 985
annemartijn Avatar asked Apr 22 '14 18:04

annemartijn


People also ask

Should every method be async?

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).

Should all code be async?

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 .

Should my database calls be asynchronous?

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.

When would you use asynchronous actions?

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.


1 Answers

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.

like image 53
Stephen Cleary Avatar answered Oct 25 '22 06:10

Stephen Cleary