Learn About Asynchronous HTTP Modules and HTTP Handlers in Asp.Net 4.5

In Asp.Net 4.5 asynchronous HTTP Handlers and Modules can be created with ease at the same time with less code complexity. In this article I will explain about the advantages of introducing asynchrony on the HTTP Pipeline and creating them in Asp.Net 4.5.

A Background on HTTP Module and HTTP Handler

HTTP Modules are the components in the Asp.Net HTTP request pipeline that interrupt all the incoming Asp.Net requests. Operations like setting up cookies, logging, authentication verification, etc., can be done using them.

HTTP Handlers are the final destination of the incoming web requests and they are responsible for processing the request and sending back the response. For example .aspx requests are processed and the response HTML is sent back to the browser by PageHandlerFactory class.

How Asynchronous Processing Gets the Edge?

In a synchronous Asp.Net request processing, there are two thread pools that take part:

  1. Asp.Net thread pool (Threads for processing the main request)
  2. I/O thread pool (Threads for performing the I/O operations – File, Database, Network, etc.)

When an Asp.Net request comes in, the request is handed over to an Asp.Net thread pool thread and the same thread takes care of processing the request and sending back the response. In the mid, if any IO related operation is performed then that job is handed over to a thread from the I/O thread pool. Note that the main Asp.Net thread pool thread will wait until the I/O thread operation is complete. This results in a blockage of the main asp.net thread. This would adversely result in the other incoming requests having to wait in the queue if the asp.net thread pool does not have any free threads to be picked up.

In an asynchronous request processing, blocking of the main thread during I/O operations can be avoided because the main Asp.Net thread pool thread will be returned back to the thread pool once the I/O operation is initiated so that it could be used by the other incoming asp.net requests. Once the I/O operation completes then it will hand over the rest of the processing to another thread from the Asp.Net thread pool. This is where you get the edge. You should decide wisely on when and where to introduce the asynchrony in Asp.Net request processing.

In summary:

  1. No blockage of the asp.net thread during an external operation.
  2. More availability of the asp.net thread pool threads.

Creating Asynchronous HTTP Module and HTTP Handler in Asp.Net 4.5

Though the previous versions of Asp.Net allowed the creation of asynchronous HTTP modules and HTTP handlers, with the introduction of Task in .net 4.0, and async / await keywords in the .net 4.5 framework, it has become much simpler. In this section I will show you about creating Asynchronous HTTP module and handler.

Create an Asp.Net 4.5 empty web application to which we will be adding the asynchronous HTTP module and handler.

Asynchronous HTTP Module

Create a class named MyAsyncHttpModule.cs and inherit from the interface IHttpmodule. In the Init event make use of the class EventHandlerTaskAsyncHelper offered by .net framework 4.5 to tie the Async method, which is going to perform an I/O operation. Below is the sample code for Async Http Module.

namespace AsyncModulesAndHandlers
{
    public class MyAsyncHttpModule: IHttpModule
    {
        #region IHttpModule Members
 
        public void Dispose()
        {
        }
 
        public void Init(HttpApplication context)
        {
            EventHandlerTaskAsyncHelper taskAsyncHelper = new EventHandlerTaskAsyncHelper(LogMessage);
            context.AddOnPostAuthorizeRequestAsync(taskAsyncHelper.BeginEventHandler, taskAsyncHelper.EndEventHandler);
        }
 
        private async Task LogMessage(object sender, EventArgs e)
        {
            //Processing will be handed over to the I/O thread.
            using (StreamWriter streamWriter = new StreamWriter("/Logs/RequestLogs.txt", true))
            {
                string logText = String.Format("The page requested is: {0}\nRequested at: {1}", ((HttpApplication)sender).Context.Request.RawUrl, DateTime.Now);
                //Main Asp.Net thread will return back to the thread pool and will not wait for the process complete.
                //Once the I/O operation is complete then the EndEventHandler will be taken care by a new thread from the Asp.Net thread pool.
                await streamWriter.WriteLineAsync(logText);
            }
        }
 
        #endregion
    }
}

Asynchronous HTTP Handler

Create a class file named MyAsyncHttpHandler.cs. Derive it from the .net 4.5 abstract class and implement the method ProcessRequestAsync. Here you can make use of the async and await keywords to make asynchronous operations. Below is the sample code.

namespace AsyncModulesAndHandlers
{
    public class MyAsyncHttpHandler : HttpTaskAsyncHandler
    {
        public override async Task ProcessRequestAsync(HttpContext context)
        {
            string responseData = await GetDataFromDatabaseAsync();
            context.Response.Write(responseData);
        }
 
        private async Task<string> GetDataFromDatabaseAsync()
        {
            //Consider this operation is reading the response data from the database (as IO operation).
            string value = "Consider it as data from DB!!";
            return value;
        }
    }
}

Happy reading!



Related Articles