Requests in ASP.NET are serviced by a collection of classes referred to as the HTTP pipeline. This pipeline has three primary points of extensibility: custom applications, custom handlers, and custom modules. A custom application is built by creating a new class that derives from HttpApplication, which happens automatically when you author a global.asax file. Custom applications can be used to perform application-level tasks by trapping events and responding to them. A custom handler is built by creating a new class that implements the IHttpHandler interface and registering that class in your application's configuration file. Custom handlers can be used as endpoints to a request in lieu of Page classes if the baggage of the Page processing architecture is not necessary. A custom module is built by creating a new class that implements the IHttpModule interface and adding event handlers to that class for any of the application-level events. Custom modules are useful for performing generic filtering and monitoring in ASP.NET applications.
Most development in ASP.NET can take place without concern for multithreading issues, because most of the classes in the pipeline are used by only one thread at a time at the instance level. It is important to understand, however, that both modules and application classes are pooled, so it is not wise to store any cross-request state in either. In some cases, it may be necessary to build asynchronous handlers to avoid clogging the ASP.NET worker thread pool with requests that take a long time to complete.