Async Action Methods - asp.net-mvc

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?

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.

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.

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.

Related

Async and CPU-Bound Operations with ASP.NET

One of the reasons async was praised for ASP.NET was to follow Nodejs async platform which led to more scalability with the freeing up of threads to handle subsequent requests etc.
However, I've since read that wrapping CPU-bound code in Task.Run will have the opposite effect i.e. add even more overhead to a server and use more threads.
Apparently, only true async operations will benefit e.g. making a web-request or a call to a database.
So, my question is as follows. Is there any clear guidance out there as to when action methods should be async?
Mr Cleary is the one who opined about the fruitlessness of wrapping CPU-bound operations in async code.
Not exactly, there is a difference between wrapping CPU-bound async code in an ASP.NET app and doing that in a - for example - WPF desktop app. Let me use this statement of yours to build my answer upon.
You should categorize the async operations in your mind (in its simplest form) as such:
ASP.NET async methods, and among those:
CPU-bound operations,
Blocking operations, such as IO-operations
Async methods in a directly user-facing application, among those, again:
CPU-bound operations,
and blocking operations, such as IO-operations.
I assume that by reading Stephen Cleary's posts you've already got to understand that the way async operations work is that when you are doing a CPU-bound operation then that operation is passed on to a thread pool thread and upon completion, the program control returns to the thread it was started from (unless you do a .ConfigureAwait(false) call). Of course this only happens if there actually is an asynchronous operation to do, as I was wondering myself as well in this question.
When it comes to blocking operations on the other hand, things are a bit different. In this case, when the thread from which the code performed asynchronously gets blocked, then the runtime notices it, and "suspends" the work being done by that thread: saves all state so it can continue later on and then that thread is used to perform other operations. When the blocking operation is ready - for example, the answer to a network call has arrived - then (I don't exactly know how it is handled or noticed by the runtime, but I am trying to provide you with a high-level explanation, so it is not absolutely necessary) the runtime knows that the operation you initiated is ready to continue, the state is restored and your code can continue to run.
With these said, there is an important difference between the two:
In the CPU-bound case, even if you start an operation asynchronously, there is work to do, your code does not have to wait for anything.
In the IO-bound case or blocking case, however, there might be some time during which your code simply cannot do anything but wait and therefore it is useful that you can release that thread that has done the processing up until that point and do other work (perhaps process another request) meanwhile using it.
When it comes to a directly-user-facing application, for example, a WPF app, if you are performing a long-running CPU-operation on the main thread (GUI thread), then the GUI thread is obviously busy and therefore appears unresponsive towards the user because any interaction that is normally handled by the GUI thread just gets queued up in the message queue and doesn't get processed until the CPU-bound operation finishes.
In the case of an ASP.NET app, however, this is not an issue, because the application does not directly face the user, so he does not see that it is unresponsive. Why you don't gain anything by delegating the work to another thread is because that would still occupy a thread, that could otherwise do other work, because, well, whatever needs to be done must be done, it just cannot magically be done for you.
Think of it the following way: you are in a kitchen with a friend (you and your friend are one-one threads). You two are preparing food being ordered. You can tell your friend to dice up onions, and even though you free yourself from dicing onions, and can deal with the seasoning of the meat, your friend gets busy by dicing the onions and so he cannot do the seasoning of the meat meanwhile. If you hadn't delegated the work of dicing onions to him (which you already started) but let him do the seasoning, the same work would have been done, except that you would have saved a bit of time because you wouldn't have needed to swap the working context (the cutting boards and knives in this example). So simply put, you are just causing a bit of overhead by swapping contexts whereas the issue of unresponsiveness is invisible towards the user. (The customer neither sees nor cares which of you do which work as long as (s)he receives the result).
With that said, the categorization I've outlined at the top could be refined by replacing ASP.NET applications with "whatever application has no directly visible interface towards the user and therefore cannot appear unresponsive towards them".
ASP.NET requests are handled in thread pool threads. So are CPU-bound async operations (Task.Run).
Dispatching async calls to a thread pool thread in ASP.NET will result in returning a thread pool thread to the thread pool and getting a another. one to run the code and, in the end, returning that thread to the thread pool and getting a another one to get back to the ASP.NET context. There will be a lot of thread switching, thread pool management and ASP.NET context management going on that will make that request (and the whole application) slower.
Most of the times one comes up with a reason to do this on a web application ends up being because the web applications is doing something that it shouldn't.

Async Controller and questions everywhere

I Have a quick question about async Controller and Actions in ASP.Net MVC 4+ (using the async/await programming model returning a Task ).
What do i risk if all my actions are async even if the underline operations are not IO Bound (for example slow web service or network communication ) and can be CPU Bound. I mean all my actions will be async no matter what code is int it . I Hope i'am clear.
Will be performance problems due to synchronisation context overhead or any other significant overhead for a public website that can have a lot of simultanous users ?
Thank you for your futur answers.
What do i risk if all my actions are async even if the underline operations are not IO Bound (for example slow web service or network communication ) and can be CPU Bound.
This is exactly what you don't want to do.
Consider what happens with a synchronous action: the request comes in, ASP.NET allocates a thread for that request, and that thread executes the action. When the action is complete, that same thread sends the response.
Now consider what happens if you "offload" an action's CPU-bound work to the thread pool (e.g., Task.Run). The request comes in, ASP.NET allocates a thread for that request, and the thread starts executing the action. When the thread hits Task.Run, it allocates another thread from the thread pool to execute the CPU-bound code. Then the asynchronous action method hits the await for that task, so the original thread is returned to the ASP.NET runtime. The other thread then finishes the work and continues on to send the response.
So, you're doing more work for every request if you have an asynchronous action that pushes CPU-bound work to the thread pool. You should never do this on ASP.NET.
I explain this in more detail on my blog.
I don't think you will run into any problems for a simple app since the async workers are running off a pool of threads with a limit number of threads. But what you may run into is a condition where the client HTTP threads are waiting on the asyn response and it exceeds a network gateway timeout. For instance, amazon ELB have a 60 second timeout. So clients can be disconnected while the async task is still running. If that happens a lot then you could end up with a lot of async tasks running and completing with no client to respond to. That would be an unfortunate condition because your clients are not getting data and your server is working for nothing.
One thing I would consider is whether or not you need async calls. I would suggest tuning up your service calls and making sure they are fast enough to address load instead of making the front end async as a workaround for the latency. For instance, using caching. Just a suggestion.
Hope it helps.

Asynchronous MVC Controllers

I'm learning about the AsyncController in ASP.NET MVC and using it with the TPL, but I'm struggling to see its need, I can understand when you would want to run an Action asynchronously to do something like send out an email, but in reality would you ever use it to return a view from an action?
For example if the Action gets some data from a database, which is set to work async, then return a View, if the data fails to retrieve in time will the View not just return with no data in the model?
Would you ever use it to return a view from an action?
The main advantage of asynchrony in ASP.NET is scalability. While the asynchronous work executes, you're not consuming any threads. This means your application will consume less memory and it may be also faster.
If the data fails to retrieve in time will the View not just return with no data in the model?
That depends on you and how exactly will you handle that failure.
Async controllers are used primarily to give up the current thread pool thread to allow other incoming connections to process work while you are waiting for a long running process to complete.
This has nothing to do with pass a view back. The process will still "block" from the end users perspective, but on the server the resources the server needs to respond to incoming requests will not be consumed.
By default, there are 250 thread pool threads per cpu core in an IIS worker process to respond to incoming connections (this can be tuned, but in general you should know what you're doing). If you have to people waiting for long requests to complete, then nobody else will be able to connect to your server until one of them finishes. Async controllers fix that problem.
You can also offload CPU bound work to a dedicated thread when using async controllers, where that was more difficult in synchronous controllers. And, it allows you to perform tasks in parallel. For instance, suppose you have to go out to 10 web sites and retrieve data. Most of the time is spent waiting for those web requests to return, and they can be done in parallel if you are doing things async.

What I should use for parallelisation of frequent HTTP requests to the REST server in iOS application: GCD or NSThread?

I'm developing an application which must extract new messages for user from the server. I have implemented this as a timer which fires every 2 seconds and call a selector which is a method that implement HTTP request and server respond processing. So I think it is quite a bad idea to do this in a main thread.I have no experience with multithreading in iOS. So I want to know what fits well for parallelizing of this task: GCD or NSThread?
You should work as far up the API stack as possible. That way you can concentrate on programming functionality and not managing threads. GCD uses threads that the system has gotten going anyway and its much more efficient than managing your own code. Its even better to aim to encapsulate your networking into NSOperations that can then be put on an NSOperationQueue and these will be executed on one or more background threads, whatever the system deems is a good number for the current power status and other things like that.
The benefit of NSOperation over a pure GCD approach is that operations can be cancelled. Once a block is committed to GCD it has to run no matter what.
If you want to encapsulate your HTTP requests in NSOperations you might be interested to know that someone has already done this for you. AFNetworking is one of the most widely regarded iOS networking stacks and uses NSOperations as its base to build on and as such is very easily multi threaded.
A good idea would be to try and encapsulate your parsing code into an NSOperation and then as your network request operations return you can create parsing operation instances and put them on another queue for processing in the background.

When should one use asynchronous controller in asp.net mvc 2?

Thus far worked with asp.net mvc1 and just started with asp.net mvc2..... what are good candidates for executing a controller asynchronously? Should i use it for long running process or some background processing? What are the pros and cons choosing asynchronous controller in asp.net mvc 2? Any suggestion...
Only use async if the operation is IO bound. A good example would be aggregating RSS feeds from multiple servers and then displaying them in a webpage.
See:
http://msdn.microsoft.com/en-us/magazine/ee336138.aspx
http://blog.stevensanderson.com/2008/04/05/improve-scalability-in-aspnet-mvc-using-asynchronous-requests/
for a good overview of asynchronous controllers.
And for more in-depth but non-MVC specific info:
http://blogs.msdn.com/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx
If your controller's method is calling some other system for example query DB or external resources with HTTP and operation lasts long then you should implement those methods as async to let the thread used to doing that be released from waiting on the results and used to service other requests. Our application is getting threads from ThreadPool and number of them is limited. Considering that limitation and the situations of having lot of application users and also long-time queries for data is it very easy to see how important it is.

Resources