Programming Microsoft ASP.NET 4 - Dino Esposito [110]
The first difference is logical. RegisterAsyncTask is an API designed to run tasks asynchronously from within a page—and not just asynchronous pages with Async=true. AddOnPreRenderCompleteAsync is an API specifically designed for asynchronous pages. That said, a couple of further differences exist.
One is that RegisterAsyncTask executes the End handler on a thread with a richer context than AddOnPreRenderCompleteAsync. The thread context includes impersonation and HTTP context information that is missing in the thread serving the End handler of a classic asynchronous page. In addition, RegisterAsyncTask allows you to set a timeout to ensure that any task doesn’t run for more than a given number of seconds.
The other difference is that RegisterAsyncTask makes the implementation of multiple calls to remote sources significantly easier. You can have parallel execution by simply setting a Boolean flag, and you don’t need to create and manage your own IAsyncResult object.
The bottom line is that you can use either approach for a single task, but you should opt for RegisterAsyncTask when you have multiple tasks to execute simultaneously.
Async-Compliant Operations
Which required operations force, or at least strongly suggest, the adoption of an asynchronous page? Any operation can be roughly labeled in either of two ways: CPU bound or I/O bound. CPU bound indicates an operation whose completion time is mostly determined by the speed of the processor and amount of available memory. I/O bound indicates the opposite situation, where the CPU mostly waits for other devices to terminate.
The need for asynchronous processing arises when an excessive amount of time is spent getting data in and out of the computer in relation to the time spent processing it. In such situations, the CPU is idle or underused and spends most of its time waiting for something to happen. In particular, I/O-bound operations in the context of ASP.NET applications are even more harmful because serving threads are blocked too, and the pool of serving threads is a finite and critical resource. You get real performance advantages if you use the asynchronous model on I/O-bound operations.
Typical examples of I/O-bound operations are all operations that require access to some sort of remote resource or interaction with external hardware devices. Operations on non-local databases and non-local Web service calls are the most common I/O-bound operations for which you should seriously consider building asynchronous pages.
Important
Asynchronous operations exist to speed up lengthy operations, but the benefits they provide are entirely enjoyed on the server side. There’s no benefit for the end user in adopting asynchronous solutions. The “time to first byte” doesn’t change for the user in a synchronous or asynchronous scenario. Using AJAX solutions would give you at least the means to (easily) display temporary messages to provide information about the progress. However, if it’s not coded asynchronously on the server, any lengthy operation that goes via AJAX is more harmful for the system than a slow-but-asynchronous classic Web Forms page.
The Page Life Cycle
A page instance is created on every request from the client, and its execution causes itself and its contained controls to iterate through their life-cycle stages. Page execution begins when the HTTP runtime invokes ProcessRequest, which kicks off the page and control life cycles. The life cycle consists of a sequence of stages and steps. Some of these stages can be controlled through user-code events; some require a method override. Some other stages—or more exactly, substages—are just not public, are out of the developer’s control, and are mentioned here mostly for completeness.
The page life cycle is articulated in three main stages: setup, postback, and finalization. Each stage might have one or more substages and is composed of one or more steps and points where events are raised. The life