There are few cases in current web applications, where it involves long running operations. For instance, a system admin uploads 1 gig of data in the system, which will be processed by the system for 30-40 minutes to be splitted and putted properly in the database system, as well as notifying other system user regarding the availability if data.
In the traditional approach of web application, the user has to wait for the whole time until the whole process needs to be completed. The modern age of web application includes a technique where the user doesn't required to be wait to complete the whole process with the current page, where as they can move on other page (or even can close the browser) or if they resides on that page the system will show a simple progress bar , which stops when the data processing (or the long running operation) completes. The corresponding technique that implies this usability feature is using an asynchronous model.
Before the asp.net 2.0 ages, creating an asynchronous model was very complex and time consuming along with several over-heads. ASP.NET 2.0 comes with a new nice feature, where we can declare and use a page easily in asynchronous style. Besides the easy implementation model, ASP.NET asynchronous page utilizes ASP.NET threads efficiently. While calling a long running database query or web service, at the moment the request reaches at the asynchronous point, the corresponding asynchronous operation starts without keeping the current ASP.NET allocated, and thus lets the thread to be returned back to the thread pool. As soon as the asynchronous process completes, another ASP.NET thread get allocated and continues accordingly. This model really improves the utilization of ASP.NET thread pool and thus improves the scalability of the corresponding web applications. More can be found here.
To make a web page asynchronous, we just have to put a property in the page directive as follows:
<%@ Page Async="true" ...
There are two different implementation model for ASP.NET 2.0 asynchronous pages, with respect to database and web-service call.
Implementation model for database
The implementation model for database query requires a "PageAsyncTask" class to be set with few event handler methods such as "Begin Event Handler", "End Event Handler", "Timeout Event Handler" etc. This task should be registered as an Asynchronous tasks to continue and complete the asynchronous scenario properly.
public partial class AsyncPageTask : System.Web.UI.Page
{
private SqlConnection _connection;
private SqlCommand _command;
private SqlDataReader _reader;
IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
{
Response.Write("Starts at: " + DateTime.Now.ToString());
_command = DAL.GetCommandForInsertRecord();
_connection = _command.Connection;
return _command.BeginExecuteReader(cb, state);
}
void EndAsyncOperation(IAsyncResult ar)
{
_reader = _command.EndExecuteReader(ar);
Response.Write(" Ends at: " + DateTime.Now.ToString());
}
void TimeoutAsyncOperation(IAsyncResult ar)
{
}
public override void Dispose()
{
if (_connection != null)
_connection.Close();
base.Dispose();
}
protected void btnClick_Click(object sender, EventArgs e)
{
Response.Write("Hello ");
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation),
new EndEventHandler(TimeoutAsyncOperation),
null
);
RegisterAsyncTask(task);
}
}
Implementation model for web service
The implementation model for web service call is much more simpler than the database query. Ii just includes creating an web service instance, followed by calling the MethodName"Async" (for instance, if the web method name is "HelloWorld" then its asynchronous method name is "HelloWorldAsync". Besides the calling the asynchronous method for a web service method, we can register it's complete event handler to perform some post completion tasks.
protected void btnClick_Click(object sender, EventArgs e)
{
Response.Write("Starts at: " + DateTime.Now.ToString());
MyWebService.WebService MyWS = new MyWebService.WebService();
MyWS.HelloWorldCompleted += new MyWebService.HelloWorldCompletedEventHandler(MyWS_HelloWorldCompleted);
MyWS.HelloWorldAsync();
}
void MyWS_HelloWorldCompleted(object sender, MyWebService.HelloWorldCompletedEventArgs e)
{
Response.Write(" Ends at: " + DateTime.Now.ToString());
}