Quantcast
Viewing latest article 3
Browse Latest Browse All 10

Asynchronous Controller in ASP.Net MVC

The AsyncController class enables us to write asynchronous action methods. Using asynchronous action methods we can write long running, non-cpu bound request which will increase a significant application performance.

Why We Need Asynchronous?
On the web server when a request is arrived, a new thread is dispatched from the thread pool and dedicated to that request until the request is being processed. So for a log running process if several users request at the same time it will reduce the threads availability as the number of thread is limited. So, at a certain time some user will get error HTTP 503 status (Server Too Busy) if the request queue is full.
Aasynchronous method comes in the scenario to mitigate the above problem of thread starvation. In ASP.NEC MVC asynchronous action is responsible for these purposes.

What happened when an asynchronous action is invoked?

1. The Web server gets a thread from the thread pool (the worker thread) and schedules it to handle an incoming request. This worker thread initiates an asynchronous operation.

2. The worker thread is returned to the thread pool to service another Web request.

3. When the asynchronous operation is complete, it notifies ASP.NET.

4. The Web server gets a worker thread from the thread pool (which might be a different thread from the thread that started the asynchronous operation) to process the remainder of the request, including rendering the response.

Asynchronous controller in use
So prior to look at asynchronous action we will first look at the synchronous action method

public class RemoteDataController : Controller
    {
        public ActionResult GetData()
        {
            RemoteServiceClient remoteServiceClient = new RemoteServiceClient();
            var data = remoteServiceClient.GetData(100);
            return View();
        }
    }

So, when a user request for the above action it will request for the remote service and until completing the whole process the current worker thread would be blocked. So the thread will not be available for other users until the process completed.

Below is the asynchronous version of the above action:

public class RemoteDataController : AsyncController
    {        
        public void GetDataAsync()
        {
            AsyncManager.OutstandingOperations.Increment();
            RemoteServiceClient remoteServiceClient = new RemoteServiceClient();
 
            Task.Factory.StartNew(() =>
                {
                    string data = remoteServiceClient.GetData(200);
                    AsyncManager.Parameters["Data"] = data;
                    AsyncManager.OutstandingOperations.Decrement();
                });
        }
 
        public ActionResult GetDataCompleted(string data)
        {
            return View((object)data);
        }
    }

The steps of asynchronous controller:


1. Instead of deriving the controller from Controller derive from AsyncController.
2. The Asynchronous action comes in pairs. First is the <Action>Async, for our case GetDataAsync. In the GetDataAsync we will create and perform our asynchronous task. And the other part of the pair is the <Action>Completed. In our case GetDataCompleted which will be called on completion of the task.
So for the action GetData First GetDataAsync will be run and after completing the task asynchronously GetDataCompleted will be called.

So any user request for GetData action will not stuck the current worker thread. Instead it will free the current thread for other users whenever it performs the log task in our case remote service call. After completing the task the user will get another thread (it might be the same or other) from the thread pool. So the the thread pool can serve more users as the worker thread is not getting stuck for a log running process.


Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing latest article 3
Browse Latest Browse All 10

Trending Articles