<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      MVC之前的那點(diǎn)事兒系列(4):Http Pipeline詳細(xì)分析(上)

      2014-06-03 08:55  湯姆大叔  閱讀(6285)  評(píng)論(7)    收藏  舉報(bào)

      文章內(nèi)容

      繼續(xù)上一章節(jié)的內(nèi)容,通過(guò)HttpApplicationFactory的GetApplicationInstance靜態(tài)方法獲取實(shí)例,然后執(zhí)行該實(shí)例的BeginProcessRequest方法進(jìn)行執(zhí)行余下的Http Pipeline 操作,代碼如下:

      // Get application instance 
      IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context);

      那GetApplicationInstance這個(gè)方法究竟做了啥呢?難道只是new一個(gè)新對(duì)象出來(lái)?感覺(jué)應(yīng)該不像,那我們就來(lái)看看HttpApplicationFactory類的GetApplicationInstance靜態(tài)方法源碼:

      internal static IHttpHandler GetApplicationInstance(HttpContext context) { 
          if (_customApplication != null)
              return _customApplication; 
       
          // Check to see if it's a debug auto-attach request
          if (context.Request.IsDebuggingRequest) 
              return new HttpDebugHandler();
      
          _theApplicationFactory.EnsureInited();
       
          _theApplicationFactory.EnsureAppStartCalled(context);
       
          return _theApplicationFactory.GetNormalApplicationInstance(context); 
      }

      里面有3行代碼我已經(jīng)標(biāo)記為粗體了,在解釋每行代碼的具體作用之前,先看看_theApplicationFactory對(duì)象實(shí)例從哪里來(lái),通過(guò)查看該字段的聲明代碼可以看到它是單例的實(shí)現(xiàn)。

      // the only instance of application factory
      private static HttpApplicationFactory _theApplicationFactory = new HttpApplicationFactory();

      第一行粗體代碼是執(zhí)行,該實(shí)例的EnsureInited方法,這個(gè)方法會(huì)通過(guò)lock的方式調(diào)用Init方法(好處自然不用多說(shuō)了吧),代碼如下:

      private void EnsureInited() {
          if (!_inited) {
              lock (this) { 
                  if (!_inited) {
                      Init(); 
                      _inited = true; 
                  }
              } 
          }
      }

      通過(guò)查找 Init方法的代碼以及其中2行如下代碼里的細(xì)節(jié),我們可以得知,這2行代碼主要是從global.asax獲取內(nèi)容,然后進(jìn)行編譯。

      _appFilename = GetApplicationFile(); 
      CompileApplication();

      所以,HttpApplicationFactory._theApplicationFactory.EnsureInited()  的方法首先檢查HttpApplicationFactory是否被初始化,如果沒(méi)有,就通過(guò)HttpApplicationFactory.Init()進(jìn)行初始化。在Init()中,先獲取global.asax文件的完整路徑,然后調(diào)用CompileApplication()對(duì)global.asax進(jìn)行編譯。

      第2行粗體的EnsureAppStartCalled方法,最終會(huì)調(diào)用如下的私有方法FireApplicationOnStart,代碼如下:

      private void FireApplicationOnStart(HttpContext context) { 
          if (_onStartMethod != null) { 
              HttpApplication app = GetSpecialApplicationInstance();
       
              app.ProcessSpecialRequest(
                                          context,
                                          _onStartMethod,
                                          _onStartParamCount, 
                                          this,
                                          EventArgs.Empty, 
                                          null); 
      
              RecycleSpecialApplicationInstance(app); 
          }
      }

      通過(guò)代碼我們能夠得知HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context)  創(chuàng)建特定的HttpApplication實(shí)例,觸發(fā)ApplicationOnStart事件,執(zhí)行ASP.global_asax中的Application_Start(object sender, EventArgs e)方法。然后在處理完事件以后就立即被回收掉,因?yàn)橄到y(tǒng)初始化只需要一次,但是其中的GetSpecialApplicationInstance里會(huì)對(duì)IIS7做一些特殊的事情,我們后面的章節(jié)會(huì)講到。

      第3行的粗體代碼是我們這里要說(shuō)的重點(diǎn),它方法里的代碼如下:

      private HttpApplication GetNormalApplicationInstance(HttpContext context) {
          HttpApplication app = null; 
      
          lock (_freeList) {
              if (_numFreeAppInstances > 0) {
                  app = (HttpApplication)_freeList.Pop(); 
                  _numFreeAppInstances--;
       
                  if (_numFreeAppInstances < _minFreeAppInstances) { 
                      _minFreeAppInstances = _numFreeAppInstances;
                  } 
              }
          }
      
          if (app == null) { 
              // If ran out of instances, create a new one
              app = (HttpApplication)HttpRuntime.CreateNonPublicInstance(_theApplicationType); 
       
              using (new ApplicationImpersonationContext()) {
                  app.InitInternal(context, _state, _eventHandlerMethods); 
              }
          }
      
          return app; 
      }

      如果在有空閑的HttpApplication實(shí)例,就直接用,如果沒(méi)有就新創(chuàng)建,然后調(diào)用InitInternal方法進(jìn)行初始化相關(guān)的內(nèi)容,最后返回該HttpApplication實(shí)例。

       

      讓我們來(lái)看看HttpApplication的核心方法InitInternal里都是干了什么事兒吧,先上代碼,有點(diǎn)多,但是很值得:

      internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { 
          Debug.Assert(context != null, "context != null");
      
          // Remember state
          _state = state; 
      
          PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); 
       
          try {
              try { 
                  // Remember context for config lookups
                  _initContext = context;
                  _initContext.ApplicationInstance = this;
       
                  // Set config path to be application path for the application initialization
                  context.ConfigurationPath = context.Request.ApplicationPathObject; 
       
                  // keep HttpContext.Current working while running user code
                  using (new DisposableHttpContextWrapper(context)) { 
      
                      // Build module list from config
                      if (HttpRuntime.UseIntegratedPipeline) {
       
                          Debug.Assert(_moduleConfigInfo != null, "_moduleConfigInfo != null");
                          Debug.Assert(_moduleConfigInfo.Count >= 0, "_moduleConfigInfo.Count >= 0"); 
       
                          try {
                              context.HideRequestResponse = true; 
                              _hideRequestResponse = true;
                              InitIntegratedModules();
                          }
                          finally { 
                              context.HideRequestResponse = false;
                              _hideRequestResponse = false; 
                          } 
                      }
                      else { 
                          InitModules();
      
                          // this is used exclusively for integrated mode
                          Debug.Assert(null == _moduleContainers, "null == _moduleContainers"); 
                      }
       
                      // Hookup event handlers via reflection 
                      if (handlers != null)
                          HookupEventHandlersForApplicationAndModules(handlers); 
      
                      // Initialization of the derived class
                      _context = context;
                      if (HttpRuntime.UseIntegratedPipeline && _context != null) { 
                          _context.HideRequestResponse = true;
                      } 
                      _hideRequestResponse = true; 
      
                      try { 
                          Init();
                      }
                      catch (Exception e) {
                          RecordError(e); 
                      }
                  } 
       
                  if (HttpRuntime.UseIntegratedPipeline && _context != null) {
                      _context.HideRequestResponse = false; 
                  }
                  _hideRequestResponse = false;
                  _context = null;
                  _resumeStepsWaitCallback= new WaitCallback(this.ResumeStepsWaitCallback); 
      
                  // Construct the execution steps array 
                  if (HttpRuntime.UseIntegratedPipeline) { 
                      _stepManager = new PipelineStepManager(this);
                  } 
                  else {
                      _stepManager = new ApplicationStepManager(this);
                  }
       
                  _stepManager.BuildSteps(_resumeStepsWaitCallback);
              } 
              finally { 
                  _initInternalCompleted = true;
       
                  // Reset config path
                  context.ConfigurationPath = null;
      
                  // don't hold on to the context 
                  _initContext.ApplicationInstance = null;
                  _initContext = null; 
              } 
          }
          catch { // Protect against exception filters 
              throw;
          }
      }

      該代碼主要有2個(gè)功能,一個(gè)是初始化大家熟悉的HttpModules,一個(gè)是通過(guò)BuildSteps執(zhí)行20多個(gè)生命周期事件的處理函數(shù)(這部分內(nèi)容,我們將在下一章節(jié)詳細(xì)講解Http Pipeline)。通過(guò)上面的代碼我們可以看出,每個(gè)功能都有一個(gè)特殊判斷,判斷IIS是否是IIS7的集成模式,如果是就有特殊的步驟,如果不是就走一般的步驟,兩者直接的差異分別是:IIS7初始化HttpModules的時(shí)候會(huì)從網(wǎng)站配置的Modules里讀取(因?yàn)镮IS7預(yù)加載CLR和大批量Modules),BuildSteps的時(shí)候, IIS7集成模式走的是自己特殊的流程(加載服務(wù)器上的HttpModules)。

      讓我們先總結(jié)一下再看代碼,InitInternal方法的主要功能如下:

      1. InitModules():根據(jù)Web.Config的設(shè)置,加載相應(yīng)的HttpModules。
      2. InitIntegratedModules():會(huì)加載IIS7集成模式下在服務(wù)器上設(shè)定的HttpModuels和Web.config里system.webserver下的HttpModuels。
      3. HookupEventHandlersForAppplicationAndModules:根據(jù)發(fā)生的事件,調(diào)用HttpApplication實(shí)例中相應(yīng)的事件處理函數(shù)。
      4. 創(chuàng)建很多實(shí)現(xiàn)IExecutionStep接口的類的實(shí)例并添加到當(dāng)前HttpApplication實(shí)例的_execSteps中,等待回調(diào)時(shí)執(zhí)行。從這里我們可以看到HttpApplication是以異步的方式處理請(qǐng)求, 對(duì)請(qǐng)求的很多處理工作都放入了_execStep等待回調(diào)時(shí)執(zhí)行。

      至此,除了20多個(gè)周期事件和Handler相關(guān)的代碼我們沒(méi)有講解,其它和HttpApplication相關(guān)的并且對(duì)我們有幫助的,已經(jīng)差不多清晰了。關(guān)于20多個(gè)周期事件和執(zhí)行Handler方面的內(nèi)容,我們下一章節(jié)再做詳細(xì)解釋。

      參考資料:

      http://msdn.microsoft.com/en-us/magazine/cc188942.aspx

      http://msdn.microsoft.com/en-us/library/bb470252.aspx

      http://www.rzrgm.cn/zhaoyang/archive/2011/11/16/2251200.html

      同步與推薦

      本文已同步至目錄索引:MVC之前的那點(diǎn)事兒系列

      MVC之前的那點(diǎn)事兒系列文章,包括了原創(chuàng),翻譯,轉(zhuǎn)載等各類型的文章,如果對(duì)你有用,請(qǐng)推薦支持一把,給大叔寫(xiě)作的動(dòng)力。

      主站蜘蛛池模板: 亚洲AV无码东方伊甸园| 亚洲av成人精品免费看| 999久久久免费精品播放| 337p粉嫩大胆色噜噜噜| 亚洲中文字幕成人综合网| 重口SM一区二区三区视频| 精品久久久久久久中文字幕| 精品国产午夜福利在线观看| 亚洲国产一区二区三区四| 无码av中文字幕免费放| 国产午夜福利在线视频| 人妻出轨av中文字幕| 风流少妇树林打野战视频| 嵊泗县| 亚洲日韩欧美一区二区三区在线| 一区天堂中文最新版在线| 国产农村激情免费专区| 亚洲av影院一区二区三区| 亚洲 欧美 唯美 国产 伦 综合| 精品无码久久久久成人漫画| 盈江县| 国产偷国产偷亚洲高清人| 色猫咪av在线网址| 国产精品久久久久久av| 久久蜜臀av一区三区| 久久精品国产亚洲av天海翼| 高级艳妇交换俱乐部小说 | av深夜免费在线观看| 国产精品中文第一字幕| 国产亚洲精品久久综合阿香| 人妻18毛片A级毛片免费看| 国产老妇伦国产熟女老妇高清| 国产欧美另类精品久久久 | 久热综合在线亚洲精品| 国产高清精品在线91| 欧美日韩性高爱潮视频| 婷婷四房播播| 国产精品一区二区三区卡| 老太脱裤让老头玩ⅹxxxx| 九九成人免费视频| 亚洲日本乱码熟妇色精品|