Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
14 Dec 2007 1  
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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here