Why Async Pages?
While reading about asynchronous web pages (Chapter 11 of Pro ASP.NET 3.5 with C# 2008), I came across a great reminder:
It’s important to understand that an asynchronous page is no faster than a normal, synchronous page. In fact, the overhead of switching to the new thread and back again is likely to make it a bit slower. The advantage is that other requests—ones that don’t involve long operations—can get served more quickly. This improves the overall scalability of your site. It’s also important to realize that the asynchronous processing takes place completely on the web server, and the web page user won’t notice any difference—wait times and postbacks will still take just as long.
To rehash an older post of mine on unnecessary parallelism in ASP.NET, the number of threads available to a web app is very limited (~20…25). Ideally, you should process a request and return a response as fast as possible. As Michaen Nygard points out, “shortening the processing time means you can handle more transactions during the same unit of time.”
However, if you hold up a request for too long, e.g. due to a long database read or a lengthy web service call, the thread you’re holding isn’t available to process other requests, nor is it doing anything useful while waiting. You gotta do something about it. This is where it’s worth to consider asynchronous processing.
Take a moment to reread the excerpt above. The important point is that “an asynchronous page is no faster than a normal, synchronous page.” It may be even a little slower due to context switching. The kicker here is the request is moved to another thread pool! The .NET Framework provides a number of
APIs for asynchronous file IO, webs services, etc, usually named
EndXxx(). These APIs use the fascinating feature called I/O completion ports which doesn’t use threads from the ASP.NET thread pool.
The book makes another great point:
Performing simultaneous asynchronous tasks is a good technique when your tasks involve different resources. It’s a bad idea if your tasks will compete for the same resource. For example, a page that performs three database queries at once isn’t a good candidate for simultaneous execution, because you’ll need to open three connections at the same time, which will probably have a negative effect on the overall scalability of your site.
At the end of the day, if you feel you need to add parallelism to your ASP.NET app, think long and hard. In most cases it won’t buy you anything.