HTTP协议/IIS 原理及ASP.NET运行机制浅析【图解】(3)

ASP.NET运行机制

在IIS6图示中我们分析到“ AppManagerAppDomainFactory 的 Create 方法为 Application 创建一个 Application Domain;通过 ISAPIRuntime 的  ProcessRequest 处理 Request,进而将流程进入到 ASP.NET Http Runtime Pipeline。”

下面我们来看一下AppDomain运行过程图示

appdomain3

AppDomain的作用,相信大家都很了解了吧.这里简明扼要的写几点:

一个AppDomain中的代码创建的对象不能由另一个AppDomain中的代码直接访问(只能使用按引用封送或者按值封送,起到了很好的隔离作用).

AppDomain可以卸载 CLR不支持从AppDomain中卸载一个程序集的能力,但可以告诉CLR卸载一个AppDomain,从而达到卸载当前包含在该AppDomain内的所有程序集.

AppDomain 可以单独保护 当宿主加载一些代码之后,可以保证这些代码不会被破坏(或读取)宿主本身使用的一些重要的数据结构.

AppDomain可以单独配置 设置主要影响CLR在AppDomain中加载程序集的方式,涉及搜索路径、版本绑定重定向、卷影复制及加载器的优化。

由以上几点可以看出AppDomain确保了Windows系统及其中运行的应用程序的健壮性。AppDomain提供了保护、配置和终止其中每一个应用程序所需的隔离性。

再来看下ProcessRequest的过程

HttpApplication_Analysis

简单分析一下上图

ProcessRequest(HttpWorkerRequest wr)中判断wr是否为null,然后判断管线是否完整,再调用ProcessRequestNoDemand(wr)方法,

并判断当前RequestQueue 是否为null,接着计算等待时间并更新管线数 CalculateWaitTimeAndUpdatePerfCounter(wr);

重置wr开始时间wr.ResetStartTime();调用ProcessRequestNow(wr)方法,并调用ProcessRequestInternal(wr)方法

继续图例

ProcessRequestInternal

ProcessRequestInternal方法如下:

 
 
  1. private void ProcessRequestInternal(HttpWorkerRequest wr)   
  2.   {   
  3.       HttpContext context;   
  4.       try   
  5.       {   
  6.           context = new HttpContext(wr, false);//由HttpWorkerRequest生成HttpContext   
  7.       }   
  8.       catch   
  9.       {  
  10.     
  11.         //常见的400错误,就是在这里捕捉到滴    
  12.           wr.SendStatus(400, "Bad Request");   
  13.           wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");   
  14.           byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");   
  15.           wr.SendResponseFromMemory(bytes, bytes.Length);   
  16.           wr.FlushResponse(true);   
  17.           wr.EndOfRequest();   
  18.           return;   
  19.       }   
  20.       wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);   
  21.       Interlocked.Increment(ref this._activeRequestCount);   
  22.       HostingEnvironment.IncrementBusyCount();   
  23.       try   
  24.       {   
  25.           try   
  26.           {   
  27.               this.EnsureFirstRequestInit(context);   
  28.           }   
  29.           catch   
  30.           {   
  31.               if (!context.Request.IsDebuggingRequest)   
  32.               {   
  33.                   throw;   
  34.               }   
  35.           }   
  36.           context.Response.InitResponseWriter();   
  37.           IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);   
  38.   //得到HttpApplication        
  39.     
  40.   if (applicationInstance == null)   
  41.           {   
  42.               throw new HttpException(System.Web.SR.GetString("Unable_create_app_object"));   
  43.           }   
  44.           if (EtwTrace.IsTraceEnabled(5, 1))   
  45.           {   
  46.               EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");   
  47.           }   
  48.           if (applicationInstance is IHttpAsyncHandler)   
  49.           {   
  50.               IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;   
  51.               context.AsyncAppHandler = handler2;   
  52.               handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);//届时 HttpApplication处理请求   
  53.           }   
  54.           else   
  55.           {   
  56.               applicationInstance.ProcessRequest(context);   
  57.               this.FinishRequest(context.WorkerRequest, context, null);   
  58.           }   
  59.       }   
  60.       catch (Exception exception)   
  61.       {   
  62.           context.Response.InitResponseWriter();   
  63.           this.FinishRequest(wr, context, exception);   
  64.       }   
  65.   } 

再看下GetApplicationInstance(context) 实例化Application的方法

 
 
  1. View Code   
  2.  internal static IHttpHandler GetApplicationInstance(HttpContext context)  
  3.  {  
  4.      if (_customApplication != null)  
  5.      {  
  6.          return _customApplication;  
  7.      }  
  8.      if (context.Request.IsDebuggingRequest)  
  9.      {  
  10.          return new HttpDebugHandler();  
  11.      }  
  12.      _theApplicationFactory.EnsureInited();  
  13.      _theApplicationFactory.EnsureAppStartCalled(context);  
  14.      return _theApplicationFactory.GetNormalApplicationInstance(context);  
  15.  } 

最后调用的GetNormalApplicationInstance方法中对当前空闲的application数目进行判断,调用

application.InitInternal(context, this._state, this._eventHandlerMethods)方法,

this.InitModules()初始化所有的Modules,包含用户自定义的HttpModules

this._stepManager.BuildSteps(this._resumeStepsWaitCallback);//管道事件序列

贴一下源码:

 
 
  1. internal override void BuildSteps(WaitCallback stepCallback)   
  2.  {   
  3.      ArrayList steps = new ArrayList();   
  4.      HttpApplication app = base._application;   
  5.      bool flag = false;   
  6.      UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;   
  7.      flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);   
  8.      steps.Add(new HttpApplication.ValidatePathExecutionStep(app));   
  9.      if (flag)   
  10.      {   
  11.          steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));   
  12.      }   
  13.      app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);   
  14.      app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);   
  15.      app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);   
  16.      app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);   
  17.      app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);   
  18.      app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);   
  19.      app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);   
  20.      app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);   
  21.      steps.Add(new HttpApplication.MapHandlerExecutionStep(app));   
  22.      app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);   
  23.      app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);   
  24.      app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);   
  25.      app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);   
  26.      steps.Add(new HttpApplication.CallHandlerExecutionStep(app));   
  27.      app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);   
  28.      app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);   
  29.      app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);   
  30.      steps.Add(new HttpApplication.CallFilterExecutionStep(app));   
  31.      app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);   
  32.      app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);   
  33.      this._endRequestStepIndex = steps.Count;   
  34.      app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);   
  35.      steps.Add(new HttpApplication.NoopExecutionStep());   
  36.      this._execSteps = new HttpApplication.IExecutionStep[steps.Count];   
  37.      steps.CopyTo(this._execSteps);   
  38.      this._resumeStepsWaitCallback = stepCallback;   
  39.  } 

到这里想必能够使大家对ASP.NET管道机制能够有一个简单的回顾.当然还有很多地方没有详细分析。

再来总结一下IIS运行过程及ASP.NET管道机制:

Request→ (Internet )  HTTP.sys 监听 → WAS (IIS6 web Admin Service /IIS7 (Windows Activation Service) 接收请求

→(传入)Application Pool's → w3wp.exe(检查URL后缀)

→(加载)ISAPI扩展[aspnet_isapi.dll] → 注册映射

构造HttpRuntime类 →ProcessRequest方法

HttpContext实例产生(Request,Response,Session  and so on…)

HttpRuntime 调用 HttpApplicationFactory加载HttpApplication对象

穿越HttpModule到达HttpHandler

简单用140个字符(即一条微博的字数微笑)概括:

Request→ (Internet ) HTTP.sys →(WAS)→Application Pool's → w3wp.exe→ISAPI→ Map→ (Pipeline)HttpWorkerRequest→AppDomain→HttpRuntime→ProcessRequest()→ HttpContext(Request,Response)→ HttpRuntime→HttpApplicationFactory→HttpApplication→ HttpModule→HttpHandler→EndRequest

以上为个人学习摘要,如有错误,欢迎指正!!

补充

1:刚刚看到dudu发的一个闪存,里面提到了Application pool 与 AppDomain 的区别 来自stackoverflow,希望对大家有所帮助.

2:WAS缩写在IIS6中的指的是(Web Admin Service),在IIS7中指的是(Windows Activation Service)  缩写一样.这个在写文章的时候注意到过,但是没有深入考虑. 理解不是很到位.  暂不妄下断言.  欢迎斧正!! :-)

参考资料:

http://www.cnblogs.com/tenghoo/archive/2009/11/04/IIS_And_ASPNET_Http_Runtime_Pipeline.html

http://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.80).aspx

http://www.cnblogs.com/panchunting/archive/2013/04/11/ASPNET_Architecture.html

后续

由于一些个人原因,放弃了原本在无锡相对安逸的工作,踏上了北漂之路,也希望在大环境下能够得到更多的锻炼与打磨.

当然,最近也正在找工作,如果您有合适的职位,烦请介绍一下,感谢之至!!

如果你觉得本文对您有所帮助,请点击一下推荐,感谢您的阅读!!

原文链接:http://www.cnblogs.com/wenthink/archive/2013/05/06/3058989.html

【编辑推荐】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值