When I first saw the Asynchronous Controllers introduced in MVC 2, I couldn't wait to start playing around. I thought that it would be a really easy to get up and running with a simple example, but after searching online for a few working examples - pretty much all of them used an event based pattern that wasn't easy to understand. In this blog post I am going to run through a really simple example that will show you the basics of Asynchronous Controllers, and show you how easy they really are.
There are some massive benefits to using Asynchronous Controllers with MVC. If your application is I/O or network limited, adding an Asynchronous Controller can help your application stay responsive. It's also a really sexy way of handling long running operations without blocking your application. In this post, I am going to run through a simple example using an Asynchronous Controller and show you just how easy it really is to get up and running. The easiest way by far is using the Task Parallel library. I have also blogged about the Task Parallel Library using Parallel Invoke, for more information please read this post.
Right, let's get started. In Visual Studio, create a new empty MVC application and add a new controller. I've called mine HomeController. Then you need to change the Controller so that it inherits from the AsyncController base class instead of the Controller base class.
Next up, I am going to add a method called IndexAysnc(). Asynchronous actions are written in a similar fashion to standard synchronous requests. It is important to name the Action Methods correctly, as they need to end in 'Async' or 'Completed'. In a synchronous controller, you would normally only have one Action Method per HTTP action. However, in an Async method, you get both Async and Completed appended to the name - but the View name will still be Index. So in this example, our URL will still be /Home/Index
If you notice in the method above, it is making use of the Task.Factory.StartNew() method that comes with the Task Parallel Library. It is a great way to add threading to your application and it also makes the code really streamline. Inside the StartNew() method I am adding some simple code to download the HTML from this website, but you could replace this with any custom long running method of your choice. Next, add the final part of the async method (Completed). If we follow the naming convention, it should be IndexCompleted.
You may also notice that in the code above that I am using AsyncManager.OutstandingOperations. This notifies the MVC pipeline of how many operations are pending completion. This is necessary because MVC has no way of knowing what operations were kicked off by the action method or when those operations are complete. When the counter hits zero, the pipeline understands that it needs to complete the overall operation.
This is just a simple method that returns the data to our view, from here you can return anything that was executed asynchronously to your View. It's that simple! If you would like to run through this example the project is available for download, please click here to download.