关闭

asp.net运行的本质

651人阅读 评论(0) 收藏 举报
IIS根据扩展名.aspx启动 aspnet_isapi.dll,aspnet_isapi.dll转交到 aspnet_wp.exe,wp是worker process的简称; wp会根据情况创建一个新的AppDomain,或重用已有的AppDomain;每个IIS有多个AppDomain。
在该AppDomain里,wp将要求转交到 ISAPIRuntime对象,该对象从ISAPI包中解构成必要的信息,调用 HttpRuntime.ProcessRequest来处理用户要求。HttpRuntime在每个AppDomain中是唯一的。HttpRuntime会创建 HttpContext和Cache两个对象,每个HttpContext管理着一个HttpSession;注意每个来访者都会对应着一个HttpContext,也意味着每个来访者都有自己的HttpSession。
HttpRuntime.ProcessRequest除了创建HttpContext和Cache,还通过请求HttpApplicationFactory,创建HttpApplication:HttpApplicationFactory先解译目录中的Global.asax,然后加载Global.dll,合并两者生成Ghost Application Class,编译此class生成HttpApplication,实例句柄返回到HttpRuntime。
在生成Ghost Application Class过程中,HttpApplicationFactory具备pooling的功能,即尽可能重用HttpApplication,除非需要新建或文件更改(如Global.asax,Global.dll);此外,此过程中的Parser也是pooling的,即如果相关文件不变化,是不会进行重新编译的。
HttpApplication在初始化的时候,相关的HttpModules会被加载,如Session、Authentication等模块,每个HttpModule都实现了IHttpModule接口。
interface IHttpModule {
void Init (HttpApplication context);
void Dispose();
}
Init在模块被加载时被调用;Dispose在模块被释放时被调用。注意Modules在HttpApplication初始化期间被加载(Init),所以可以在Init中拦截一些HttpApplication后续的功能,比如SessionState Module可以拦截HttpApplication.BeginRequest/EndRequest等事件。
HttpRuntime在创建HttpApplication后,调用HttpApplication.ProcessRequest,此方法将执行权转交到HttpHandler对象。

注意,在AppDomain中,HttpRuntime是唯一的,但不同的来访者有不同的HttpApplication,但由于HttpApplicationFactory的pooling作用,一些已有的HttpApplication会被重用。
为什么HttpApplication可以共享Cache和Application State? 注意Cache和Application State是由httpRuntime管理,而HttpRuntime是唯一的。
每个HttpApplication对应一组HttpModules,而不是共享。但对于session,每个session的储存是由CacheInternal对象来组织,多个SessionState Module实际是访问同一个底层的CacheInternal。而一个HttpRuntime是管理着一个CacheInternal,因此Session不会受到多个HttpApplication的影响。

HttpHandler是根据mechine.config(Framework目录下)和web.config (在虚拟目录下)指定的HttpHandler来创建。.aspx对应着 System.Web.UI.PageHandlerFactory类,先创建一个PageParser对象 (实际上还有UserControlParser,PageParser也有Cache的机制,检查HttpRuntime中的Cache对象,如果已有,会直接使用已有对象来创建Page实现,而不会重复),该对象找到对应的.aspx文件,加载并解译,生成ControlBuilder对象群,然后这些对象群交到PageCompiler进行编译,生成Ghost Page Class。生成page后,HttpApplication调用 BeginProcessRequest进行请求的处理(Page本身实现了IHttpAsyncHandler接口)。
Page在接到请求后,首先判断是否 Post-back模式 (查询有无__VIEWSTATE和__EVENTTARGET);决定模式后,page进行Initialize Control (调用InitRecursive,实质是迭代执行 Control.OnInit),而后
1. 如果是Post-back,则运行Post-back机制,此时Page先调用 LoadPageViewStates加载view States数据(实质是迭代调用各control的LoadViewStates),即Page还原到上一次执行后的状态,此后,调用ProcessPostData,加载各控件的Post data (注意控件如果要参与ProcessPostData,必须要实现IPostBackDataHandler接口,并在page对象中RegisterRequiresPostBack),接下来RaiseChangeEvent,发出OnChange事件,以及处理Post-back事件,如果控件已经RegisterRequiresRaiseEvent的话,此时将调用RaisePostBackEvent,否则根据__EVENTTARGET执行 Post-back。
2. 不管是否Post-back,此时开始load各个 controls,实质是调用各控件的OnLoad,此后调用OnPreRend,(注意html和javascript的render时就不能再修改,所以如果要修改,一定要在此时机进行),再调用SaveViewState将控件当前状态存入__VIEWSTATE,最后调用RenderControl将HTML写出,完成整个Page。

注意几个事件的次序,Init事件发生时所有控件处在默认值,Load事件发生前控件已经还原到先前的状态。此后PreRender也是个很重要的事件,需要注意。

在处理完用户请求后,HttpApplication会根据IHttpHandler.IsReusable决定是否重用或释放。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:26809次
    • 积分:417
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:11篇
    • 译文:0篇
    • 评论:4条
    我的链接