ASP.NET底層架構探索之處理請求

來源:互聯網
上載者:User

        當一個請求到來時,它被路由到ISAPIRuntime.ProcessRequest()方法.這個方法調用HttpRuntime.ProcessRequest方法,它作一些重要的事情(用Reflector查看System.Web.HttpRuntime.ProcessRequestInternal方法):

  ·為請求建立一個新的HttpContext執行個體

  ·擷取一個HttpApplication執行個體

  ·調用HttpApplication.Init()方法來設定管道的事件

  ·Init()方法觸發開始ASP.NET管道處理的HttpApplication.ResumeProcessing()方法。

  首先一個新的HttpContext對象被建立並用來傳遞ISAPIWorkerRequest(ISAPI ECB的封裝器).這個上下文在整個請求的生命週期總都是可用的並總可以通過靜態屬性HttpContext.Currect來訪問.正像名字所暗示的那樣,HttpContext對象代表了當前活動請求的上下文因為他包含了在請求生命週期中所有典型的你需要訪問的重要對象:Request,Response,Application,Server,Cache.在請求處理的任何時候HttpContext.Current給你訪問所有這些的能力.

  HttpContext對象也包含一個非常有用的Items集合,你可以用它來儲存針對特定請求的資料.內容物件在請求周期的開始時被建立,在請求結束時被釋放,所有在Items集合中儲存的資料只在這個特定的請求中可用.一個很好的使用的例子是請求日誌機制,當你通過想通過在Global.asax中掛接Application_BeginRequest和Application_EndRequest方法記錄請求的開始和結束時間(象在列表3中顯示的那樣).HttpContext對你就非常有用了-如果你在請求或頁面處理的不同部分需要資料,你自由的使用它.

  列表3-使用HttpContext.Items集合使你在不同的管道事件中儲存資料

protected void Application_BeginRequest(Object sender, EventArgs e)
{
 //*** Request Logging
 if (App.Configuration.LogWebRequests)
  Context.Items.Add("WebLog_StartTime",DateTime.Now);
}

protected void Application_EndRequest(Object sender, EventArgs e)
{
 // *** Request Logging
 if (App.Configuration.LogWebRequests)
 {
  try
  {
   TimeSpan Span = DateTime.Now.Subtract( (DateTime) Context.Items["WebLog_StartTime"] );
   int MiliSecs = Span.TotalMilliseconds;
   // do your logging
   WebRequestLog.Log(App.Configuration.ConnectionString,true,MilliSecs);
  }
 }
}

  一旦上下文被設定好,ASP.NET需要通過HttpApplication對象將收到的請求路由到適合的應用程式/虛擬目錄.每個ASP.NET應用程式必須被設定到一個虛擬目錄(或者Web根目錄)而且每個”應用程式”是被單獨的處理的。

  HttpApplication類似儀式的主人-它是處理動作開始的地方。

  域的主人:HttpApplication

  每個請求都被路由到一個HttpApplication對象上.HttpApplicationFactory類根據應用程式的負載為你的ASP.NET應用建立一個HttpApplication對象池並為每個請求分發HttpApplication對象的引用.對象池的大小受machine.config檔案中ProcessModel鍵中的MaxWorkerThreads設定限制,預設是20個(譯註:此處可能有誤,根據Reflector反編譯的代碼,池的大小應該是100個,如果池大小小於100,HttpApplicationFactory會建立滿100個,但是考慮到會有多個線程同時建立HttpApplication的情況,實際情況下有可能會超過100個)。

  對象池以一個更小的數字開始;通常是一個然後增長到和同時發生的需要被處理的請求數量一樣.對象池被監視,這樣在大負載下它可能會增加到最大的執行個體數量,當負載降低時會變回一個更小的數字。

  HttpApplication是你的Web程式的外部封裝器,而且它被映射到在Global.asax裡面定義的類上.它是進入HttpRuntime的第一個進入點.如果你查看Global.asax(或者對應的代碼類)你會發現這

個類直接繼承自HttpApplication:

public class Global : System.Web.HttpApplication

  HttpApplication的主要職責是作為Http管道的事件控制器,所以它的介面主要包含的是事件.事件掛接是非常廣泛的,包括以下這些:

  ·BeginRequest

  ·AuthenticateRequest

  ·AuthorizeRequest

  ·ResolveRequestCache

  ·AquireRequestState

  ·PreRequestHandlerExecute

  ·…Handler Execution…

  ·PostRequestHandlerExecute

  ·ReleaseRequestState

  ·UpdateRequestCache

  ·EndRequest

  每個事件在Global.assx檔案中以Application_首碼開頭的空事件作為實現.例如, Application_BeginRequest(), Application_AuthorizeRequest()..這些處理器為了便於使用而提供因為它們是在程式中經常被使用的,這樣你就不用顯式的建立這些事件處理委託了。

  理解每個ASP.NET虛擬目錄在它自己的應用程式定義域中運行,而且在應用程式定義域中有多個從ASP.NET管理的池中返回的HttpApplication執行個體同時運行,是非常重要的,這是多個請求可以被同時處理而不互相妨礙的原因。

  查看列表4來獲得應用程式定義域,線程和HttpApplication之間的關係。

  列表4-顯示應用程式定義域,線程和HttpApplication執行個體之間的關係。

private void Page_Load(object sender, System.EventArgs e)
{
 // Put user code to initialize the page here
 this.ApplicationId = ((HowAspNetWorks.Global) HttpContext.Current.ApplicationInstance).ApplicationId ;
 this.ThreadId = AppDomain.GetCurrentThreadId();

 this.DomainId = AppDomain.CurrentDomain.FriendlyName;

 this.ThreadInfo = "ThreadPool Thread: " + System.Threading.Thread.CurrentThread.IsThreadPoolThread.ToString() +"<br>Thread Apartment: " +
System.Threading.Thread.CurrentThread.ApartmentState.ToString();

 // *** Simulate a slow request so we can see multiple
 // requests side by side.
 System.Threading.Thread.Sleep(3000);
}

  這是隨sample提供的demo的一部分,啟動並執行結果在圖5中顯示.運行兩個瀏覽器,開啟這個示範頁面可以看到不同的ID。

  圖5-你可以通過同時運行多個瀏覽器來簡單的查看應用程式定義域,應用程式集區執行個體和請求線程是如何互動的。當多個請求同時發起,你可以看到線程ID和應用程式ID變化了,但是應用程式定義域還是同一個。

  你可能注意到在大多數請求上,當線程和HttpApplication ID變化時應用程式定義域ID卻保持不變,雖然它們也可能重複(指線程和HttpApplication ID).HttpApplication是從一個集合中取出,

在隨後到來的請求中可以被複用的,所以它的ID有時是會重複的.注意Application執行個體並不和特定的線程綁定-確切的說它們是被指定給當前請求的活動線程。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.