Friday, July 25, 2014

Step by step how to create Asynchronous Action Methods to improve scalability

In this tutorial we'll learn how to create Asynchronous Action Methods in Asp.Net MVC Applications. When we think of scalability, we talk about the operating system assigning a LIMITED number of threads to the incoming requests being taking care by the w3wp Asp.Net process .
If each request must perform some heavy process, or wait for some Web Service to get data from, the thread will get stuck until the arrival of the response from that Web Service .
MVC 4 - 5 has an answer for that kind of scalability issue: asynchronous action methods.
In this example we'll start an application as serial , and see the request-response using certain thread, and being stuck in wait.
Following we'll upgrade the Action Method making it asynchronous, meaning that although the user will not see any variation in terms of response speed, the web server will not collapse under thousands of frozen threads waiting for heavy services. The web page getting a response from the Asynchronous Action Method will display different threads IDs, as follows:

First think we need for this example is to create a WCF service to serve our MVC application, so open a new project and add a WCF to it:

Add an Interface:

Then add the operation  implementing the interface:

And of course define the returned Object as a Data Contract:

Now we are done with the Web Service. Build and run it, and return to your MVC app, to add a reference to the WCF service:

If the PROXY code is not automatically generated, and you get an error as follows:

That may be because you are using the IIS Express web server, and not the developer's server that ships with Visual Studio:

The IIS will identify that there is a cross-domain issue here, and avoid to call the WCF, failing at constructing the Proxy. So open the web.config and add the following code to perform cross-domain calls:

If it persists in not building the Proxy classes , as follows:

Then check that the "reuse types" in the Service Reference Configuration is UNCHECKED:

Rebuild the application and confirm that this time the Proxy classes have been built:

If everything's OK, we can code an Action method which calls the Web Service. This is a serial Action method, which begins and ends on the same thread:

The rendered web page looks as follows:

As you can see, the initial thread is the same as the final thread, and BOTH the client (browser) as the web server (our Action method) got STUCK for some seconds.
Now we'll upgrade the action method making it asynchronous:
1) Add the async directive to the action method
2) Cast the ActionResult to Task<ActionResult>
3) Call the asynchronous version of the WCF service method ( ....... Async() )
4) Wait for the WCF response using the "await" operator:

I also added an await Task.Delay(3000) to make the action method more heavy and slow to return a response. Now you can see that the browser awaits the same time for a web server response, but the thread  does not get stuck since it is resumed by another thread created when the WCF response triggers the callback , which is managed on a NEW THREAD:

If you liked the Twitter Bootstrap ScrollSpy used in the web page markup at this tutorial, you can copy it from this tutorial.

That's all!!  In this tutorial we've learned  how to create Asynchronous Action Methods in Asp.Net MVC Controllers.
Happy programming.....
        By Carmel Schvartzman
כתב: כרמל שוורצמן