Introduction
This article explains why we need Async Action Methods in ASP.NET MVC4 Applications.
Consider a situation where you have a traditional ASP.NET web application deployed into your IIS Server. Assume one of your methods in your application's Registration Form has the functionality that may take more than a minute to process the data on clicking the Save button.
You could see the screen is non-responsive and you were blocked from doing actions on other parts of the site after clicking the Save button. This is because your functionality is processed synchronously. This is where we need to use asynchronous programming like async and await.
Before answering the question in the title of this article, let us have a brief intro of async and await.
What is Async/wait?
The async and await keywords were introduced in C# 5.0. async executes a method asynchronously whereas await indicates that the current method is waiting asynchronously for the process/method that needs to complete.
For more detail, please look at these C-SharpCorner Async Articles.
Why do we need Async Actions?
Well, of course you need to have asynchronous action methods when you need a non-blocking responsive UI or your request to an action method has functionalities regarding IO operations or you are providing options to cancel the long running request. To understand more, we will explain how the ASP.NET request will be processed.
In the IIS Web server, the .Net framework manages a thread pool to process the ASP.NET service requests. When the server receives a request, it is assigned to a thread. If the thread processes the request in an synchronous manner, then it can't handle another request that has arrived.
In large applications, if the Web Sever processes the concurrent long-running requests then all the threads may be blocked and the server will reject the request with the HTTP 503 Status, in other words "Server Too Busy".
In this situation, if the Web Server processes the request in an asynchronous manner then the server won't be blocked to process another request, because:
- If the Web server receives a request, then it will be assigned to a thread from the thread pool to handle the request.
- The thread simply initiates an asynchronous operation and returns to the thread pool to service another request.
- When the asynchronous operation is complete, the web server notifies ASP.NET.
- Since the thread is returned to the thread pool, the web server again picks another thread to process the remaining part of the request (rendering the response).
It's always better to explain the article with an example.
Setup the Project
Just follow the procedure described in this article to create an ASP.NET MVC4 web application. Once you are done with the project setup, we need to add extra methods to HomeController. Let's go through the code.
View
- @model int
-
- <h1>Index Page</h1>
View is returned with number @Model asynchronously.
The Index view renders the number returned by the Index asynchronous method of HomeController
NonAction Method
Create a "nonaction" method DoSomethingAsync() in HomeController to use with our example app. Instead of this method, you can use any other API call or other layer's method related to the view.
- [NonAction]
- public async Task<int> DoSomethingAsync()
- {
- await Task.Delay(10000);
- return 10000;
- }
In this above "nonaction" method DoSomethingAsync (), we are returning a Task of type int after a period of 10 seconds. It is always a good practice to decorate all the functions that are not Actions with the NonAction attribute.
Async in Action
We will use Async with the Index action as shown below.
- public async Task<ActionResult> Index()
- {
- int num = await DoSomethingAsync();
- return View(num);
- }
In this action method, we are asynchronously waiting for the DoSomethingAsync () and then we are returning the view with the number 10000.
In the preceding figure, we can see the async and await keywords are used to make our Index action asynchronously.
When we request the Index view, the Web Server assigns the request to the Thread I to process. Thread I starts processing the request. When the Thread I finds the await, it initiates a process to handle the DoSomethingAsync() and returns to the ThreadPool to serve another request.
Once the DoSomethingAsync() is completed, the Web Server assigns the Thread II to process the remaining part of the Index action.
This is how to make an Action method an asynchronous action method to have a responsive UI.
Note: Source code is uploaded without packages (DLLs) due to file upload restrictions.