可以看出他们的顺序,是先有Start,后有init start是针对所有Application实例的,而init只针对某一application实例. 老外原话: Actually, Application_Start and Application_End events are only fired once during the ASP.NET application's lifetime. The Application.Init and Dispose event are two event specific to each HttpApplication class(and our global.asax class which derive from HttApplication). And for each ASP.NET request, there will has a dedicated HttpAppliction instance associated with it, so the "Init" and "Dispose" event fires once for each ASP.NET request.Also, for other events listed, they also fires once in each ASP.NET request, but they're more coupled with ASP.NET's server-side pipeline where we can do some customization on the request.
我的一个不太成熟的理解是,针对IIS 7的Integrated Pipeline模式。用户开始向IIS请求页面时,IIS服务会启动一个Worker Process(w3wp)来处理这个请求。在w3wp.exe启动时,它会加载CLR并且初始化ASP.NET模型。我想HttpApplication实例应该就是这个时候建立的,初始化的几个函数也是这个时候执行。假如有多个请求到来,那么IIS应该会根据配置启动更多的WP来处理请求。而完成工作处于空闲状态的WP则可以被调度来处理新的请求。这样就出现了ls被多次提到的HttpApplication实例被重用的情况了。如果长时间没有新的请求进来,IIS最后会把这些WP都回收掉。而且根据IIS的配置,WP也会定期被回收。所以HttpApplication缓冲池在OS级别的表现,其实就是WP进程池了,由IIS服务负责管理。希望这些说明能帮助lz更好的理解IIS和ASP.NET模型。 ---------- Support Engineer Microsoft
{ protected void Application_Start(object sender, EventArgs e)
{
string str = Application["A"] != null ? (string)Application["A"] : "";
str += "11";
Application["A"] = str;
} protected void Application_End(object sender, EventArgs e)
{ } public override void Init()
{
string str = Application["A"] != null ? (string)Application["A"] : "";
str += "a22";
Application["A"] = str;
base.Init();
}
}
页面: Response.Write(Application["A"].ToString());
start是针对所有Application实例的,而init只针对某一application实例.
老外原话:
Actually, Application_Start and Application_End events are only fired once
during the ASP.NET application's lifetime.
The Application.Init and Dispose event are two event specific to each
HttpApplication class(and our global.asax class which derive from
HttApplication). And for each ASP.NET request, there will has a dedicated
HttpAppliction instance associated with it, so the "Init" and "Dispose"
event fires once for each ASP.NET request.Also, for other events listed, they also fires once in each ASP.NET
request, but they're more coupled with ASP.NET's server-side pipeline where
we can do some customization on the request.
index.html是普通的html页面, 没有任何服务器端的代码; default.aspx是一个aspx页面, 含有服务器端代码.用户第一次访问这个站点, 如果它请求的是index.html页面, 因为index.html是一个静态页面, 不需要.NET来处理, 所以IIS 就直接Response给客户端了, 这种情况下不会创建HttpApplication的实例.
如果请求default.aspx页面, 因为这个页面中包含服务器端代码, 要用.NET来处理, 在这种情况下, 就会创建一个HttpApplication实例来处理这个请求.
Application的Start事件发生在: Web站点部署好之后, 第一次访问default.aspx的时候, 以后再访问default.aspx, 就不会再触发Application的start事件.
在一个aspx页面里, 如果上面有一个<asp:button>, 当你点击按钮的时候, 会引发回传. 回传在某种意义上来讲也是一个请求, 只不过在回传的时候, 会提交相应的参数(如: <asp:TextBox>, <input>中的内容)到服务器端, 服务器获取这些参数, 处理守之后再将结果Response给客户端.如果在学习asp.net之前使用过php, asp或者jsp的经历, 理解这些概念会比较容易, asp.net把这些概念封装的太好了.
我不是很明白,那第一次访问其他.aspx呢?会不会触发Start事件?
但不是每一个请求都会创建HttpApplication实例, 服务器上有一个HttpApplication池, 保存一定数量的HttpApplication实例, HttpApplication在处理完请求之后就会回到HttpApplication池中, 然后就可以被重用.
============
不会,我的意思是访问default2.aspx和default.aspx是相同的,这两人文件访问任何一个都会触发Start事件,但是只是第一次(这个第一次不是指每个页面的第一次,而是整个应用程序生命周期的第一次)
整个应用程序生命周期可以这样理解,即从这个网站第一次请求到站点重启之前.那么,站点架设好后,如果你访问了任何一个aspx文件(default.aspx或default2.aspx)都会触发App.._Start事件,从这以后,你再访问任何aspx就不是每一次了,
private HttpApplication GetNormalApplicationInstance(HttpContext context)
{
HttpApplication application = null;
lock (this._freeList)
{
if (this._numFreeAppInstances > 0)
{
application = (HttpApplication)this._freeList.Pop();
this._numFreeAppInstances--;
if (this._numFreeAppInstances < this._minFreeAppInstances)
{
this._minFreeAppInstances = this._numFreeAppInstances;
}
}
}
if (application == null)
{
application = (HttpApplication)HttpRuntime.CreateNonPublicInstance(this._theApplicationType);
using (new ApplicationImpersonationContext())
{
application.InitInternal(context, this._state, this._eventHandlerMethods);
}
}
return application;
}
我们页面中用到的Application其实就是HttpApplicationState
从顺序上讲Application_Init事件比Application_Start事件在前.
但是,正和所有的Init事件一样,原则上,不要再这个事件上写code的. 事实上,对于Application的Init的事件,我刚才做上面做了一个断点,发现也根本不给机会得到焦点,所以你就不用考虑这个初始化事件了.Application_BeginRequest则是只要有请求就会发生的.作为一个问题探讨,这是一个不错的问题. 但是作为使用来讲也没有必要去记住它,如果你想知道的话,只要加上几个断点一比较,立马就知道了. 所以, 学到解决问题的方案,比明白这个问题,意义更重大.
----------
Support Engineer
Microsoft