HttpHandler和HttpModule

 

   区别:“HttpHandler是处理请求的主要对象”,但HttpModule却可以随意指定将某个请求交给某个处理器来执行!

甚至,HttpModule也可以直接处理请求,完全不给HttpHandler工作的机会!

   HttpModule的加载方式:前面我说过“Asp.net会为每个请求分配一个HttpApplication对象”,在每个HttpApplication对象的初始化操作中, 它会加载所有在web.config中注册的HttpModule。由于Asp.net并不是只创建一个HttpApplication对象,而是多个HttpApplication对象, 因此每个HttpModule的Init事件是有可能被多次调用的。 许多人喜欢在这里做各类初始化的操作,那么请注意在这里修改静态变量成员时的线程安全问题。 特别地,如果要执行程序初始化的操作,那么还是把代码放在Global.asax的Application_Start中去处理吧, HttpModule的Init事件并不合适。

   为HttpModule选择订阅合适的管线事件:这是非常重要的,订阅不同的事件,产生的结果也会不一样。 原因也很简单,在Asp.net运行环境中,并不只有一个HttpModule,某个HttpModule的判断可能要依据其它HttpModule的输出结果, 而且在某些(晚期的)管线事件中,也不能再修改输出数据。 在后面的示例中,DirectProcessRequestMoudle订阅了PostAuthorizeRequest事件,如果订阅BeginRequest事件或许将得到更好的性能, 但是,在BeginRequest事件中,身份认证模块还没有工作,因此每个请求在这个事件阶段都属于“未登录”状态。

   

httpmodule看不见的性能问题

前面我介绍了HttpModule的重要优点:高重用性。只要写好一个HttpModule可以放在任何Asp.net项目中使用,非常方便。

不过,再好的东西也不能滥用。HttpModule也可以对性能产生负面影响。 原因也很简单:对于每个Asp.net请求,每个HttpModule都会在它们所订阅的事件中, 去执行一些操作逻辑。这些操作逻辑或许对一些请求是无意义的,但仍会执行。 因此,计算机将会白白浪费一些资源去执行一些无意义的代码。

知道了原因,解决办法也就很清楚了:
1. 去掉不需要的HttpModule
2. 在每个HttpModule的事件处理器中,首先要确定是不是自己所需要处理的请求。对一些不相关的请求,应该立即退出。

在我们创建一个Asp.net项目时,如果不做任何修改,微软已经为我们加载了好多HttpModule 。请看以下代码:

protected void Page_Load(object sender, EventArgs e)
{
    HttpApplication app = HttpContext.Current.ApplicationInstance;        
    StringBuilder sb = new StringBuilder();

    foreach( string module in app.Modules.AllKeys ) 
        sb.AppendFormat(module).Append("<br />");

    Response.Write(sb.ToString());
}

输出结果如下:

总共有14个。
哎,大多数是我肯定不会用到的,但它们却被加载了,因此,在它们所订阅的事件中,它们的代码将会检查所有的请求, 那些无意义的代码将有机会执行。如果您不想视而不见,那么请在web.config中做类似的修改,将不需要的Module移除。

<httpModules>
    <remove name="Session"/>
    <remove name="RoleManager"/>
</httpModules>
posted @ 2011-09-13 11:04  苏先森1989  阅读(555)  评论(2编辑  收藏  举报