星辉

星月同辉 e路随行
.net/vs2005/c#/web/ajax
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[转]ASP.NET 应用程序生命周期补充

Posted on 2007-11-24 14:21  star163  阅读(179)  评论(0编辑  收藏  举报
1. HttpApplication

在每个 ASP.NET 应用程序中存在一个 HttpApplication 池,由底层环境根据资源和需求动态创建一定数量的 HttpApplication 对象来处理相关请求。每个 HttpApplication 每次只能处理一个请求,但它会负责该请求的整个生命周期,直到该请求处理结束后,重新放回池中,等待下一个任务分配。

我们编写的 HttpApplication 的事件代码,会动态绑定到当前的处理 HttpApplication 对象。如果创建了 Global.asax 文件,ASP.NET 会将其编译为从 HttpApplication 类派生的类,然后使用该派生类表示应用程序。

Global.Application_Start 事件只是在第一个 HttpApplication 实例处理请求时触发,而且整个应用程序生命周期中只会触发一次。Global.Application_End
在卸载应用程序之前对每个应用程序生命周期调用一次。而 HttpApplication.Init 则对 HttpApplication 的每个实例都调用一次,用于初始化这些实例对象。

2. HttpModule

HttpModule 在装载完成后,其实例就会在整个应用程序生命周期内存在。因此我们需要小心编写相关代码,避免多线程造成的资源同步问题。建议 HttpModule 做成无状态的,不要使用线程锁,否则将导致整个应用程序的效率降低。

测试代码
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public class HelloWorldModule : IHttpModule
{
  DateTime d;

  public HelloWorldModule()
  {
    d = DateTime.Now;
    HttpContext.Current.Response.Write(string.Format("HelloWorldModule Constructor {0}<br>", d));
  }

  public void Init(HttpApplication context)
  {
    context.BeginRequest += new EventHandler(context_BeginRequest);
  }

  void context_BeginRequest(object sender, EventArgs e)
  {
    HttpContext.Current.Response.Write(string.Format("HelloWorldModule {0}/{1}<br>", d, DateTime.Now));
  }

  public void Dispose()
  {
  }
}

3. HttpHandler

IHttpHandler 的 IsReusable 属性决定了其生命周期。如果 IsReusable = true,那么它将被放入对象池中重复使用,否则会在每次请求时创建新实例。HttpHandler 每次只能处理一个请求,因此池中可能有多个相关实例。

缺省情况下,ASP.NET 对于图片和静态 Html 文档是不做处理的(由 IIS 处理),而一旦使用 HttpHandler "path=*.*" 接管则势必造成所有的资源都需要托管代码进行处理,造成应用程序系统性能的降低。这种存在缺陷的方案在很多 URL Rewrite 中被使用。

测试代码
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public class HelloWorldHandler : IHttpHandler
{
  DateTime d;

  public HelloWorldHandler()
  {
    d = DateTime.Now;
    HttpContext.Current.Response.Write(string.Format("HelloWorldHandler Constructor {0}<br>", d));
  }

  public bool IsReusable
  {
    get { return true; }
  }

  public void ProcessRequest(HttpContext context)
  {
    context.Response.Write(string.Format("HelloWorldHandler {0}/{1}<br>", d, DateTime.Now));
  }
}

附:ASP.NET Request 流程
uploads/200608/16_175251_refaspnetpipelineprocessing.gif