The following are the steps for using an asynchronous page after adding a Web reference:
- Creating a class implementing IAsyncResult and a custom proxy class.
- Creating an asynchronous page.
- Implementing the BeginProcessRequest, EndProcessRequest, MyCallback methods.
- Deriving a page from the asynchronous page and using the response data.
The implementation of this approach is similar to that of the asynchronous PreRequestHandler execution approach. I’ll highlight and mention those differences.
Step 1. Creating a class implementing IAsyncResult and a custom proxy class
The only change made on Step 1 of the asynchronous PreRequestHandler execution approach is to store an HttpContext object. We will pass it in the base.ProcessRequest call later.
Step 2. Creating an asynchronous page
The Page class itself implements the IHttpHandler interface, and thus services requests synchronously. To change a given .aspx page to service requests asynchronously, it is necessary to implement IHttpAsyncHandler in the Page-derived class. Our asynchronous page will derive System.UI.Page and implement the IHttpAsyncHandler interface.
Handlers that implement the IHttpAsyncHandler interface must implement two additional methods besides the standard methods of IHttpHandler, which are implemented by System.UI.Page. The first, BeginProcessRequest, is called by the application class instead of directly calling the ProcessRequest. It is then up to the handler to launch a new thread to process the request and then immediately return from the BeginProcessRequest method, passing back a reference to a valid IAsyncResult instance so that the runtime knows the operation is complete. The other method, EndProcessRequest, is called when the request processing is complete and can be used to clean up any allocated resources if necessary.
Step 3. Implementing the BeginProcessRequest, EndProcessRequest, MyCallback methods
I highlight a few changes made on Step 2 of the asynchronous PreRequestHandler execution approach. We have to access Request indirectly through Context, otherwise ASP.NET will try to get Request through the call System.Web.UI.Page.get_Request while the Page object is not initialized correctly at that time. We also need to store context in the MyAsyncResult object. It is important that I invoke the base class scope of ProcessRequest (with the original signature as defined in the IHttpHandler interface), which performs the standard request processing of a page, this time it will be performed on the thread pool thread instead of the primary request thread.
Step 4. Deriving a page from the asynchronous page and using the response data.