There are two options of extending the page-processing behavior of ASP.NET. These are HttpHandlers and HttpModules. I’ve already written a post about the former, which you can find here. HttpHandlers are parts of the ASP.NET infrastructure which are responsible for processing a given request. Each request is served by exactly one handler. You can create your custom handlers by implementing the IHttpHandler or IHttpAsyncHandler interface.
Modules on the other hand provide a way to work with every given request. There are multiple modules working in ASP.NET for each request, for example, they are responsible for authentication, sessions, caching, and much more. Even better, they don’t override the default execution of the page life-cycle, so your forms will show up as usual. With the help of the IHttpModule interface, you can register events of the page life-cycle such as BeginRequest, or PostLogRequest. You can then add your own code into these events.
But what is the appropriate use of them?
There may be several situations when your web pages need to handle long-running processes, for example, query information from a slow database, work with the file system, etc. In this case, you’d need to use asynchronous pages.
First you need to understand that asynchronous pages aren’t actually faster, than their synchronous counterparts. Using them won’t affect the speed of your site, just the scalability of it. The second thing to know is that you shouldn’t use the traditional multithreading ways when you are working with ASP.NET. ASP.NET serves incoming requests from its on thread pool; one thread is responsible for the whole lifetime of the request. When you use the Threading namespace, you are getting a thread from the very same thread pool ASP.NET itself uses. So you shouldn’t do it. Instead you should use asynchronous pages, which in fact gets their working threads from another thread pool, thus freeing up the ones in ASP.NET’s, which it can use to serve more requests.