Brendan Tompkins [MVP]

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Going Beyond AJAX - What's Really Needed for Asynchronous Web Development

To me, you can’t get too far into the whole Web2.0/Ajax/Mashup/Whatevr discussion without coming up with a method of handling long running web requests.  AJAX helps us in the area of providing a responsive UI during web requests, but it only gets us so far.  The more we begin to mash together all these remote webservice calls, fetch  xml data to display and perform lots of real work in our web applications, the greater the need to go beyond AJAX and use real-life honest to goodness asynchronous method invocation on the server. 

What? I thought AJAX was Asynchronous?

In a sense, AJAX isn’t really asynchronous at all when it comes to HTTP requests.  An AJAX web request is a synchronous web request just like any other.  All AJAX solutions really are doing is using the browser’s built in threading (via JavaScript) to make multiple web requests for you, and then updating the page when the server responds.  These are really client-side hat-tricks, and will only get you so far and requires that the data you’re fetching on the servers is readily available.  What happens when the server doesn’t respond for ten minutes or even more?

You will run into problems with page requests that bump up against ASP.NET’s ScriptTimeout (which is set at 90 seconds by default).  AJAX or no AJAX, if your web method takes longer than your ScriptTimeout, you’re going to have problems.  You could try to guess the length of time that this will take and set your script timeout to some really large value, but here you’re just guessing what will work, and you run into other problems as well.  This article here nicely describes the general problem you’re faced with with requests timing out.

Consider the following Code

protected void Button_Click(object sender, EventArgs e)
{
       int totalSeconds = 5;
      
Thread.Sleep(totalSeconds * 1000);
       Label2.Text =
"Our Long Running Method finished at " + DateTime.Now.ToLongTimeString() + " and took " + totalSeconds + " seconds to complete";

}

If you crank your RequestTimeout down by adding this line to the Web.Config file:

<httpRuntime executionTimeout="1"/>

… you’ll see this screen, AJAX or no AJAX:

So How Do I Build Truly Asynchronous Web Applications?

As far as I can see it, and you should never trust me, but you have two good choices for making applications that can properly handle long running requests:

1) Use a message queue.  This is often a good choice where you need a guarantee that the process completed. You could use MSMQ or something else to make sure you’ve got the ability to reliably process requests on the server. 

2) Use Asynchronous Method Delegation on the server, create a polling mechanism  let the user know when the method has finished.  This “Fire and Forget” method of server side processing is a good, simple, straightforward method of doing work on the server. In fact, the most basic method of doing this is so simple, that you can implement this with very little code:

protected void Button1_Click(object sender, EventArgs e)
{
        LongRunningMethodAsync();
}

private delegate int LongRunningMethodDelegate();

/// <summary>
/// The Long running method async call.
/// </summary>
private IAsyncResult LongRunningMethodAsync()
{
   
LongRunningMethodDelegate longRunningDelegate = new LongRunningMethodDelegate(LongRunningMethod);
   
IAsyncResult ar = longRunningDelegate.BeginInvoke(new AsyncCallback(LongRunningMethodCallback), null);
   
return ar;

/// <summary>
/// The long running method callback.
/// </summary>
private void LongRunningMethodCallback(IAsyncResult ar)
{
   
AsyncResult aResult = (AsyncResult)ar;
   
LongRunningMethodDelegate longRunningDelegate = (LongRunningMethodDelegate)aResult.AsyncDelegate;
   
int totalSeconds = longRunningDelegate.EndInvoke(ar);
}

/// <summary>
/// The long running method.
/// </summary>
private int LongRunningMethod()

   
Random rand = new Random(Guid.NewGuid().GetHashCode());
    int mseconds = rand.Next(90000, 100000);
    Thread.Sleep(mseconds);    
    return (int) (mseconds / 1000);
}

So Do we need AJAX?

YES!  Ajax is a very important piece of the puzzle, and solves many of the problems faced with creating responsive web User Interfaces.  In fact, the combination of AJAX using something like ATLAS with Asynchronous Method Delegation can really add up to some powerful stuff.  I’ve put together a small sample application that shows how to use ATLAS to create a progress bar that shows the status of the long running method, called using Asynchronous delegation on the server.

This application uses ATLAS to provide the AJAX user interface, and presents three link buttons that call methods both asynchronously and synchronously on the server with the ScriptTimeout property set really low to simulate long running request problems.   It also uses a cool feature of ATLAS, the TimerControl, to provide the polling code necessary to update the UI and show a progress bar.  Download the code here to try it out for yourself.  I’ve had to rip out the ATLAS script stuff because of the ATLAS eula, but download ATLAS, and copy the Microsoft.Web.Atlas.dll to the bin directory, and the ATLAS Scripts to the ScriptLibary directory and you should be able to experiment with this code.

Further Reading

Fritz Onion has a great MSDN article titled Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code and also mentions that the above solution actually uses a thread from the thread pool, so it wont help with issues of scaling an application that has a lot of long running operations. To get around this you’d want to create your own threads, pool and manage them by hand, something I’m not comfortable doing on my own Wink [;)].  But if you need to scale an application AND provide lots of long running processes at once, you’ll want to look there.

-Brendan

Technorati Tags: , ,


Posted 04-18-2006 5:31 PM by Brendan Tompkins

[Advertisement]

Comments

Simon wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-19-2006 12:53 AM
Interesting article.  Regarding you point about rolling your own threadpool, I wouldn't even consider it unless you're just interested in the process as there are a number of implementations already available.

The best that I've come across is SmartThreadPool (http://www.codeproject.com/csharp/SmartThreadPool.asp) which is IMO excellent and affords a great deal of control (max/min workers, post completion call backs, exception handling, perfmon integration).

Just thought this might prove useful.
Dan F wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-19-2006 5:40 AM
Alex Russell wrote about similair issues here and called long running requests Comet [he made the term up :)] - http://alex.dojotoolkit.org/?p=545
There's a follow up by Dr Phil Windley here - http://www.irishdev.com/NewsArticle.aspx?id=2173

It'd be good if there was a mod_pubsub or similair built right into IIS so this would actually scale for large applications.
Charles F wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-19-2006 9:14 AM
Pretty interesting info here.  I was looking into the server-side asynchronous implementation for some background work on custom AJAX controls.  The SmartThreadPool on CodeProject is indeed a great piece of work.
Brendan wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-19-2006 9:21 AM
Simon, thanks for pointing out SmartThreadPool..  Nice!

Dan, Comet looks very interesting... It'd be pretty funny if we spent the last ten years developing loosely connected techinques for building apps, and we discover that the best way of doing things is a big fat open connection to the server.  I'll definitely be doing more reading on this.
Jason Haley wrote Interesting Finds
on 04-19-2006 1:01 PM
Dan F wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-19-2006 6:49 PM
Agreed :)

I can't think of (or haven't come across) too many situations where absolute liveness of the data is crucial. Usually some kind of delay is acceptable so you can fall back to polling. Reporting on progress of long running async server side tasks is about the only one I deal with regularly. For that I usually run with a hidden iframe pumping back script blocks (the forever frame technique) and it works really well. Makes for some amazingly smooth progress bar updates!
Alexander Kleshchevnikov wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-21-2006 6:37 PM
Hi Brendan,

Yes, it's interesting but what about security? If everyone has ability to run "heavy processes" on the server won't it slow down it? It also can help to make DOS attacks etc. So my guess it's importent to use only fast request/response pairs as soon as possible on public area of sites.
Brendan wrote re: Going Beyond AJAX - What's Really Needed for Asynchronous Web Development
on 04-21-2006 8:13 PM
Alexander,

Not sure about that concern.  You either have long running work to do, or you don't.  Of course if you can do the work quickly, you should.  

I think you prevent DOS attacks in other ways, but that is definitely something to think about.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?