關於ASP.NET與CLR相互關係的一些總結

來源:互聯網
上載者:User

CLR(COM伺服器)

      CLR作為一個COM伺服器實現在MSCorWks.dll檔案中。安裝.NET Framework時,表示CLR的COM伺服器被註冊到Windows的註冊表裡。

MSCorEE.dll(墊片)

      MSCorEE.dll的職責是判斷建立何種版本的CLR。 非託管應用程式宿主調用MSCorEE.dll(shim)中CorBindToRuntimeEx函數或者另一個相似的函數來建立CLR COM的執行個體。     

      一台機器可以安裝多個版本的CLR,但在機器中只有一個版本的MSCorEE.dll檔案。

      以上兩者之間的關係如下代碼所示(c++):     MSCorEE.dll(墊片)---->CLR(COM伺服器)

#include <Windows.h>
#include <MSCorEE.h>
#include <stdio.h>
#pragma comment(lib,"mscoree.lib")
int main(int argc, CHAR* argv[])
{
    ICLRRuntimeHost *pClrHost;
    //調用<MSCorEE.h>中的CorBindToRuntimeEx()產生COM伺服器
    HRESULT hr= CorBindToRuntimeEx(NULL, NULL, NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrHost); 
    //啟動clr
    pClrHost->Start();   
     //............................其他動作   
     //終止clr
     pClrHost->Stop();
     getchar();
     return 0;
}

 

 

應用程式定義域(AppDomain)

    一個應用程式定義域是一組程式集的一個容器。應用程式定義域的全部目的就是提供隔離性。

     為一個單獨的Windows進程,該進程中運行著一個CLR COM伺服器。該CLR中每個應用程式定義域都有自己的載入器堆。(系統域,共用域,預設域#1,其他域#2)

     一些特殊的程式集如MSCorLib.dll,它需要被所有的應用程式定義域共用,那麼他就以一種對應用程式定義域保持中立的方式被載入,由CLR維護一個特殊的載入器堆。

 

線程與應用程式定義域的關係

     線程與應用程式定義域沒有一對一的關係。多個應用程式定義域可以位於一個Windows進程中,所以一個線程可以執行一個應用程式定義域中的代碼,然後又執行另一個應用程式定義域中的代碼。從CLR的角度看,線程每次只能執行一個應用程式定義域中的代碼。線程可以通過Thead的靜態方法GetDomain來請求CLR當前正在那個應用程式定義域中執行。

 

關於卸載的問題

     一旦CLR載入到Windows的進程,就永遠不會被卸載,要想卸載進程中的CLR,只能終止進程,導致Windows清理該進程使用的所有資源。

     共用域的程式集永遠不會被卸載,回收它們的唯一方式就是終止Windows進程。

     卸載一個應用程式定義域(預設域#1,其他域#2)可以導致CLR卸載應用程式定義域中的所有程式集,並且釋放應用程式定義域的載入器堆。

 

ASP.NET 應用程式

  ASP.NET是一個ISAPI DLL(實現於ASPNET_ISAPI.DLL中)。

     當用戶端請求一個由ASP.NET ISAPI DLL處理的URL時(第一次),ASP.NET會建立一個背景工作處理序(ASPNET_wp.exe / w3wp.exe即宿主,背景工作處理序是一個寄宿有CLR COM伺服器的Windows進程)。

      CLR為該Web程式建立一個新的應用程式定義域。(參考上面的圖)

      CLR將必要的程式集載入到建立的應用程式定義域中。

      CLR建立一個Web應用程式類型的執行個體,調用其中方法響應用戶端請求。隨著Web應用程式的運行,如果代碼中引用到了更多類型,CLR會繼續將必要的程式集載入到當前Web應用程式的應用程式定義域中。

  當更多的用戶端向一個已經啟動並執行Web應用程式發出請求時,ASP.NET不會再去建立新的應用程式定義域,相反,它會使用現有的應用程式定義域,建立一個新的Web應用程式類型的執行個體,並調用其中的方法。這些方法被JIT編譯成了本地代碼,所以後續用戶端的請求處理效能將會有所提高。

 

      看下我們的背景工作處理序,如下工作管理員中所示:

 

ASP.NET 應用程式生命週期的各個階段
(一)使用者從 Web 服務器請求應用程式資源(對應檔副檔名)

     ASP.NET 應用程式的生命週期以瀏覽器向 Web 服務器發送請求為起點。ASP.NET 是 Web 服務器下的 ISAPI 擴充。Web 服務器接收到請求時,會對所請求的檔案的副檔名進行檢查,確定應由哪個 ISAPI 擴充處理該請求,然後將該請求傳遞給合適的 ISAPI 擴充。ASP.NET 處理已映射到其上的副檔名,如 .aspx、.ascx、.ashx 和 .asmx。

 

(二)ASP.NET 接收對應用程式的第一個請求。
     當 ASP.NET 接收到對應用程式中任何資源的第一個請求時,名為 ApplicationManager 的類會(1)建立一個應用程式定義域。在應用程式定義域中,(2)將HostingEnvironment 類建立一個執行個體,該執行個體提供對有關應用程式的資訊(如儲存該應用程式的檔案夾的名稱)的訪問。下面的關係圖說明了這種關係:

 

  運行ASP.NET的進程為W3WP.EXE

 

      編寫下述代碼,我們可以觀察一下HostingEnvironment 的各種屬性:

 1 <script runat="server">
 2   protected void Page_Load(object sender, EventArgs e)
 3   {
 4       StringBuilder sb = new StringBuilder();
 5       sb.Append(System.Web.Hosting.HostingEnvironment.ApplicationID).Append("<br/>")
 6           .Append(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath).Append("<br/>")
 7            .Append(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath).Append("<br/>")
 8             .Append(System.Web.Hosting.HostingEnvironment.SiteName).Append("<br/>")
 9              .Append(System.Web.Hosting.HostingEnvironment.ApplicationHost.ToString());      
10       Response.Write(sb.ToString());    
11   }
12 </script>

 

 

     輸出內容為:

a215d83d                                                   //ApplicationID
E:\MVC\Jasen\Jasen.Web\                                    //儲存該應用程式的檔案夾的名稱
/
預設網站
System.Web.Hosting.SimpleApplicationHost 

 

 

(三)為每個請求建立 ASP.NET 核心對象。
     ASP.NET 建立並初始化核心對象,如 HttpContext、HttpRequest 和 HttpResponse。HttpContext 類包含特定於當前應用程式請求的對象,如 HttpRequest 和 HttpResponse 對象。HttpRequest 對象包含有關當前請求的資訊,包括 Cookie 和瀏覽器資訊。HttpResponse 對象包含發送到用戶端的響應,包括所有轉譯輸出和 Cookie。
 
(四)將 HttpApplication 對象分配給請求
     初始化所有核心應用程式物件之後,將通過建立 HttpApplication 類的執行個體啟動應用程式。如果應用程式具有 Global.asax 檔案,則 ASP.NET 會建立 Global.asax 類的一個執行個體,並使用該衍生類別表示應用程式。MVC  Global.asax檔案內容如下:

 1  public class MvcApplication : System.Web.HttpApplication
 2     {
 3         protected void Application_Start()
 4         {            //AreaRegistration.RegisterAllAreas();
            //RegisterGlobalFilters(GlobalFilters.Filters);
            //ViewEngines.Engines.Add(new ViewEngine());            //RegisterRoutes(RouteTable.Routes);
 5             //請求 ASP.NET 應用程式中第一個資源時調用。在應用程式的生命週期期間僅調用一次 
 6             //Application_Start 方法。可以使用此方法執行啟動任務,如將資料載入到緩衝中以及初始化靜態值。 
 7 
 8             //在應用程式啟動期間應僅設定待用資料。
 9         }
10 
11         public override void Init()
12         {
13             base.Init();//在建立了所有模組之後,對 HttpApplication 類的每個執行個體都調用一次。
14         }
15 
16         public override void Dispose()
17         {
18             base.Dispose();//在銷毀應用程式執行個體之前調用。可使用此方法手動釋放任何非託管資源。
19         }
20 
21         public void Application_End()
22         {
23             //在卸載應用程式之前對每個應用程式生命週期調用一次。
24         }
25     }

 

 

     HttpApplication 進程的一個執行個體每次只處理一個請求。Application_Start 和 Application_End 方法,在應用程式定義域的生命週期期間,ASP.NET 僅調用這些方法一次,而不是對每個 HttpApplication 執行個體都調用一次。

 
(五)由 HttpApplication 管線處理請求。在處理該請求時將由 HttpApplication 類執行以下事件。

1.對請求進行驗證,將檢查瀏覽器發送的資訊,並確定其是否包含潛在惡意標記。

2.如果已在 Web.config 檔案的 UrlMappingsSection 節中配置了任何 URL,則執行 URL 對應。

3.引發 BeginRequest 事件。

4.引發 AuthenticateRequest 事件。引發 PostAuthenticateRequest 事件。

5.引發 AuthorizeRequest 事件。引發 PostAuthorizeRequest 事件。

6.引發 ResolveRequestCache 事件。引發 PostResolveRequestCache 事件。

7.根據所請求資源的副檔名(在應用程式的設定檔中映射),選擇實現 IHttpHandler 的類,對請求進行處理。如果該請求針對從 Page 類派生的對象(頁),並且需要對該頁進行編譯,則 ASP.NET 會在建立該頁的執行個體之前對其進行編譯。

8.引發 PostMapRequestHandler 事件。

-----------------------------------------------------------------------------------------------------------------------

9.引發 AcquireRequestState 事件。引發 PostAcquireRequestState 事件。

10.引發 PreRequestHandlerExecute 事件。

11.為該請求調用合適的 IHttpHandler 類的 ProcessRequest 方法。例如,如果該請求針對某頁,則當前的頁執行個體將處理該請求。             一般處理檔案ashx的ProcessRequest():速度較快

12.引發 PostRequestHandlerExecute 事件。

13.引發 ReleaseRequestState 事件。引發 PostReleaseRequestState 事件。

-----------------------------------------------------------------------------------------------------------------------

14.如果定義了 Filter 屬性,則執行響應篩選。

15.引發 UpdateRequestCache 事件。引發 PostUpdateRequestCache 事件。

16.引發 EndRequest 事件。

17.引發 PreSendRequestHeaders 事件。

18.引發 PreSendRequestContent 事件。
 

       2年多了,回過來再重新溫習一次。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.