How to execute long running jobs from a web client (using ASP.NET 1.1 and 2.0)






4.32/5 (7 votes)
An useful way to call time consuming back-end processes/Stored Procedure calls from the client.
Introduction
Web application users often report to developers that they are experiencing time-out issues while waiting for a process to complete. This process may be a Web-Service call from the back-end, a Stored Procedure call, a remote process call etc. So, it is quite obvious that execution time for them will vary and it will not be a wise decision to increase the client time-out setting accordingly. The solution to this problem is a client-callback, and again, it will not only solve time-out issues but also informs the user about the current state of the process.
Using the code
Implement IHttpAsyncHandler
to perform an AsyncCallback
. To do this, add a .ashx file to your project and inherit IHttpAsyncHandler
, IRequiresSessionState
in your web handler class (in my example, it is AsyncTaskHandler
). In order to initiate an asynchronous call to an HTTP event handler, override "IAsyncResult IHttpAsyncHandler.BeginProcessRequest(...)
" and "void EndProcessRequest(...)
" in the web handler class.
public IAsyncResult BeginProcessRequest(HttpContext context,
System.AsyncCallback cb, object extraData)
{
// Get the current Cycle
object data = context.Request["ProcessNo"];
// Create a result object to be used by ASP.NET
AsyncRequestResult result = new AsyncRequestResult(context, cb, data);
// Create a new request object to perform the main logic
AsyncRequest request = new AsyncRequest(result);
// Create a new worker thread to perform the work
// Notice that this will not remove a thread from the CLR ThreadPool.
ThreadStart start = new ThreadStart(request.Process);
Thread workerThread = new Thread(start);
// Start the work
workerThread.Start();
// Return the AsynResult to ASP.NET
return result;
}
Keep in mind the reusability of your code and object oriented programming concepts. Create a class file as AsyncRequest
which will handle the web request, and another class file as AsyncRequestResult
to manage the response. The process call will be initiated from the client using JavaScript. The JavaScript will call the .ashx using "Microsoft.XMLHTTP
".
function postRequest( url )
{
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
// 'true' specifies that it's a async call
xmlhttp.Open("POST", url, true);
// Register a callback for the call
xmlhttp.onreadystatechange =
function ()
{
if (xmlhttp.readyState == 4)
{
var response = xmlhttp.responseText;
document.getElementById('lblMessage').innerHTML = response;
stopProgressBar();
}
}
// Send the actual request
xmlhttp.Send();
}
In ASP.NET 2.0, client callback can be implemented in a more easier way, though it still uses XMLHTTP
internally. The client callback feature really consists of two things: the ICallbackEventHandler
interface and the Page.GetCallbackEventReference
method. The architecture boils down to the following basic steps. The Page.GetCallbackEventReference
method and its overloads will create JavaScript code snippets that you need to place on the client side. These code snippets contain code that sends an HTTP request back to the page (using the XMLHTTP
object under the hood). The request is then handled on the server side by a Web control that implements the ICallbackEventHandler
interface. In most cases, that Web control is the page itself, but you can have specific user controls or Web controls that react to the request. Once the request has been handled, the result is then passed back to the client through another JavaScript function whose sole purpose is to react to the result of the request.