17

I was looking at ASP.NET MVC 5 templates and I have notice that many of the actions and marked as async:

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { }

When should I do this on an MVC action? When it contains access to a database?

If I call a repository inside the action should I also use Task to make it async?

3 Answers 3

11

The core of your questions is: When should I make my MVC actions async? See http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should-my-database-calls-be-asynchronous.aspx for a good discussion of the issue. He talks about the database only, but his points carry over.

Essentially, almost never call the database in an async way.

For database applications using async operations to reduce the number of blocked threads on the web server is almost always a complete waste of time.

Don't be detracted by people telling you to always use async IO if possible. Async is all the rage right now. Lot's of irrational advice is being spread.

Sign up to request clarification or add additional context in comments.

2 Comments

Should be changed, the referenced article has an update from 28 November 2012 stating..."The combination of await, async, and the Task object makes it much easier for you to write asynchronous code in .NET 4.5. Now that EF 6 is supporting Async Query and Save, you should take advantage of asynchronous programming"
@PaulHatcher I don't agree with that conclusion at all. See my other pieces on this topic: stackoverflow.com/a/25087273/122718 and stackoverflow.com/a/12796711/122718. If the entire community jumps on a new cool technology and nobody really says why then you should start asking questions.
9

Entity Framework 6 (used by default with MVC 5) now supports async database calls, so the action method signatures have been update to reflect async being used. The simple answer is that whenever you have a task that could potentially involve waiting, use async. Hopefully, your database queries won't take long enough to roundtrip to actually benefit much from async, but if your database falls down or is being hammered particularly hard, it'll at least help to not deadlock IIS in the process.

11 Comments

This advice needs justification.
@usr: What kind of justification are you looking for? The justification is already there. You'll give IIS some breathing room to field additional requests if the database server is taking a particularly long time responding to requests for some reason. The nature of async means that while the thread is in a wait-state it can be returned to the pool to do other work instead of sitting there locked, waiting for the task to complete.
If you expect the DB to respond in 10ms on average and it takes 10s you can return all the threads you want. The app is down. Threads are not scarce in ASP.NET. There are hundreds by default and no common DB can benefit from so many parallel requests. The case for async DB calls is weak.
1) Threads are scarce. In a typical setup, a web server might have only 1000 to play with. 2) Each request requires at least one thread, so the fact that you have "hundreds" is really not that impressive. If you're fine with your web server grinding to a halt if it has to field more than 1000 simultaneous request, go ahead and stick with sync. 3) You're assuming that every single web request must make a call to the DB. Just because the DB is running slow or down completely doesn't mean that your website has to go down with it.
Almost no website in the world needs to handle 1000 concurrent requests. For example Stack Overflow never does despite being a top 100 site. This only happens if all those requests do is wait for something for a long time. Like a webservice or a websocket. Those are great cases for async. A database is totally overloaded if it gets 1k concurrent requests. This architecture is not viable so the point of sync or async is moot here. To phrase it differently: You don't get more throughput or better latency by making DB calls async. Which is the only point in doing so.
|
5

Here's an article what lists some uses cases when using tasks may have benefit and some uses cases when may have the opposite effect. The answer is not this simple every time, this is why the last point about testing.

Quote from http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4

In general, use synchronous methods for the following conditions:

  • The operations are simple or short-running.
  • Simplicity is more important than efficiency.
  • The operations are primarily CPU operations instead of operations that involve extensive disk or network overhead. Using asynchronous action methods on CPU-bound operations provides no benefits and results in more overhead.

In general, use asynchronous methods for the following conditions:

  • You're calling services that can be consumed through asynchronous methods, and you're using .NET 4.5 or higher.
  • The operations are network-bound or I/O-bound instead of CPU-bound.
  • Parallelism is more important than simplicity of code.
  • You want to provide a mechanism that lets users cancel a long-running request.
  • When the benefit of switching threads out weights the cost of the context switch. In general, you should make a method asynchronous if the synchronous method waits on the ASP.NET request thread while doing no work. By making the call asynchronous, the ASP.NET request thread is not stalled doing no work while it waits for the web service request to complete.
  • Testing shows that the blocking operations are a bottleneck in site performance and that IIS can service more requests by using asynchronous methods for these blocking calls.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.