How to use the IHttpAsyncHandler in ASP.NET
I’ve known about the IHttpAsyncHandler interface for a long time, but never really had the time to play around with it. After a brief web search I realized that not many people have. There are no easy to understand articles or blog posts on the subject, so I thought I’d investigate and share.
Basically, the IHttpAsyncHandler interface allows you to serve content asynchronously from a HTTP handler. This is great when you need to free up the worker thread to do processing like IO work etc. ASP.NET actually uses fewer threads when it runs asynchronously, which is great for performance and scalability. That’s because each thread is returned much faster to the thread pool.
The IHttpAsyncHandler is very similar to IHttpHandler interface, but with two extra methods to override – BeginProcessRequest and EndProcessRequest. From there you invoke a delegate to handle the processing asynchronously. It sounds complicated, but it really isn’t. Here is an example that removes the complicated stuff and gives you one single method to modify.
The code
The example is a handler that is used to serve files for download. Serving a file requires IO access and therefore it is a great candidate for asynchronous serving. As you can see, the ServeContent method is all there is needed for the specific task of serving files. Just modify it to whatever purpose you find fit.
public class AsyncFileHandler : IHttpAsyncHandler
{
/// <summary>
/// You only have to modify this method.
/// </summary>
private void ServeContent(HttpContext context)
{
string filePath = context.Server.MapPath(context.Request.QueryString.ToString());
if (File.Exists(filePath))
{
context.Response.TransmitFile(filePath);
}
else
{
context.Response.Write("File does not exist");
context.Response.StatusCode = 404;
context.Response.End();
}
}
#region IHttpAsyncHandler Members
private AsyncProcessorDelegate _Delegate;
protected delegate void AsyncProcessorDelegate(HttpContext context);
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
_Delegate = new AsyncProcessorDelegate(ProcessRequest);
return _Delegate.BeginInvoke(context, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
_Delegate.EndInvoke(result);
}
#endregion
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
ServeContent(context);
}
#endregion
}
There is actually very little reason to use the IHttpHandler interface anymore.
Important! This is an example on how to use the IHttpAsyncHandler and not to serve files. Do not use the file serving method in production code.
Download
Download the AsyncFileHandler.cs file below and put it in the App_Code directory. Then add this XML fragment to the web.config:
<httpHandlers>
<add verb="*" path="*file.axd" type="AsyncFileHandler" />
</httpHandlers>
Comments
Comments are closed