本主題概述 ASP.NET 應用程序的生命週期,列出了重要的生命週期事件,並描述了您編寫的代碼將如何適應於應用程序生命週期。本主題中的信息適用於 IIS 5.0 和 IIS 6.0。有關 IIS 7.0 中的 ASP.NET 應用程序生命週期的信息,請參見 IIS 7.0 的 ASP.NET 應用程序生命週期概述。
在 ASP.NET 中,若要對 ASP.NET 應用程序進行初始化並使它處理請求,必須執行一些處理步驟。 此外,ASP.NET 只是對瀏覽器發出的請求進行處理的 Web 服務器結構的一部分。 瞭解應用程序生命週期非常重要,這樣才能在適當的生命週期階段編寫代碼,達到預期的效果。
下表描述了 ASP.NET 應用程序生命週期的各個階段。
階段 |
說明 |
||||
---|---|---|---|---|---|
用戶從 Web 服務器請求應用程序資源。 |
ASP.NET 應用程序的生命週期以瀏覽器向 Web 服務器(對於 ASP.NET 應用程序,通常爲 IIS)發送請求爲起點。 ASP.NET 是 Web 服務器下的 ISAPI 擴展。Web 服務器接收到請求時,會對所請求的文件的文件擴展名進行檢查,確定應由哪個 ISAPI 擴展處理該請求,然後將該請求傳遞給合適的 ISAPI 擴展。 ASP.NET 處理已映射到其上的文件擴展名,如 .aspx、.ascx、.ashx 和 .asmx。
|
||||
ASP.NET 接收對應用程序的第一個請求。 |
當 ASP.NET 接收到對應用程序中任何資源的第一個請求時,名爲 ApplicationManager 的類會創建一個應用程序域。 應用程序域爲全局變量提供應用程序隔離,並允許單獨卸載每個應用程序。 在應用程序域中,將爲名爲 HostingEnvironment 的類創建一個實例,該實例提供對有關應用程序的信息(如存儲該應用程序的文件夾的名稱)的訪問。 下面的關係圖說明了這種關係: 如果需要,ASP.NET 還可對應用程序中的頂級項進行編譯,其中包括 App_Code 文件夾中的應用程序代碼。 有關更多信息,請參見本主題後面的“編譯生命週期”。 |
||||
爲每個請求創建 ASP.NET 核心對象。 |
創建了應用程序域並對 HostingEnvironment 對象進行了實例化之後,ASP.NET 將創建並初始化核心對象,如 HttpContext、HttpRequest 和 HttpResponse。 HttpContext 類包含特定於當前應用程序請求的對象,如 HttpRequest 和 HttpResponse 對象。 HttpRequest 對象包含有關當前請求的信息,包括 Cookie 和瀏覽器信息。 HttpResponse 對象包含發送到客戶端的響應,包括所有呈現的輸出和 Cookie。 |
||||
將 HttpApplication 對象分配給請求 |
初始化所有核心應用程序對象之後,將通過創建 HttpApplication 類的實例啓動應用程序。 如果應用程序具有 Global.asax 文件,則 ASP.NET 會創建 Global.asax 類(從 HttpApplication 類派生)的一個實例,並使用該派生類表示應用程序。
創建 HttpApplication 的實例時,將同時創建所有已配置的模塊。 例如,如果將應用程序這樣配置,ASP.NET 就會創建一個 SessionStateModule 模塊。 創建了所有已配置的模塊之後,將調用HttpApplication 類的 Init 方法。 下面的關係圖說明了這種關係: |
||||
由 HttpApplication 管線處理請求。 |
在處理該請求時將由 HttpApplication 類執行以下事件。 希望擴展 HttpApplication 類的開發人員尤其需要注意這些事件。
|
在應用程序的生命週期期間,應用程序會引發可處理的事件並調用可重寫的特定方法。 若要處理應用程序事件或方法,可以在應用程序根目錄中創建一個名爲 Global.asax 的文件。
如果創建了 Global.asax 文件,ASP.NET 會將其編譯爲從 HttpApplication 類派生的類,然後使用該派生類表示應用程序。
HttpApplication 進程的一個實例每次只處理一個請求。 由於在訪問應用程序類中的非靜態成員時不需要將其鎖定,這樣可以簡化應用程序的事件處理過程。 這樣還可以將特定於請求的數據存儲在應用程序類的非靜態成員中。 例如,可以在 Global.asax 文件中定義一個屬性,然後爲該屬性賦一個特定於請求的值。
通過使用命名約定 Application_event(如 Application_BeginRequest),ASP.NET 可在 Global.asax 文件中將應用程序事件自動綁定到處理程序。 這與將 ASP.NET 頁方法自動綁定到事件(如頁的 Page_Load 事件)的方法類似。 有關詳細信息,請參見 ASP.NET 頁生命週期概述。
Application_Start 和 Application_End 方法是不表示 HttpApplication 事件的特殊方法。 在應用程序域的生命週期期間,ASP.NET 僅調用這些方法一次,而不是對每個 HttpApplication 實例都調用一次。
下表列出在應用程序生命週期期間使用的一些事件和方法。 實際遠不止列出的這些事件,但這些事件是最常用的。
事件或方法 |
說明 |
---|---|
Application_Start |
請求 ASP.NET 應用程序中第一個資源(如頁)時調用。 在應用程序的生命週期期間僅調用一次 Application_Start 方法。 可以使用此方法執行啓動任務,如將數據加載到緩存中以及初始化靜態值。 在應用程序啓動期間應僅設置靜態數據。 由於實例數據僅可由創建的 HttpApplication 類的第一個實例使用,所以請勿設置任何實例數據。 |
Application_event |
在應用程序生命週期中的適當時候引發,請參見本主題前面的應用程序生命週期表中列出的內容。 Application_Error 可在應用程序生命週期的任何階段引發。 由於請求會短路,因此 Application_EndRequest 是唯一能保證每次請求時都會引發的事件。 例如,如果有兩個模塊處理 Application_BeginRequest 事件,第一個模塊引發一個異常,則不會爲第二個模塊調用 Application_BeginRequest 事件。 但是,會始終調用 Application_EndRequest 方法使應用程序清理資源。 |
在創建了所有模塊之後,對 HttpApplication 類的每個實例都調用一次。 |
|
在銷燬應用程序實例之前調用。 可使用此方法手動釋放任何非託管資源。 有關更多信息,請參見清理非託管資源。 |
|
Application_End |
在卸載應用程序之前對每個應用程序生命週期調用一次。 |
在第一次對應用程序發出請求時,ASP.NET 按特定順序編譯應用程序項。 要編譯的第一批項稱爲頂級項。 在第一次請求之後,僅當依賴項更改時纔會重新編譯頂級項。 下表描述編譯 ASP.NET 頂級項的順序。
Item |
Description |
---|---|
App_GlobalResources |
編譯應用程序的全局資源並生成資源程序集。 應用程序的 Bin 文件夾中的任何程序集都鏈接到資源程序集。 |
App_WebResources |
創建並編譯 Web 服務的代理類型。 所生成的 Web 引用程序集將鏈接到資源程序集(如存在)。 |
Web.config 文件中定義的配置文件屬性 |
如果應用程序的 Web.config 文件中定義了配置文件屬性,則生成一個包含配置文件對象的程序集。 |
App_Code |
生成源代碼文件並創建一個或更多個程序集。 所有代碼程序集和配置文件程序集都鏈接到資源和 Web 引用程序集(如果有)。 |
Global.asax |
編譯應用程序對象並將其鏈接到所有先前產生的程序集。 |
在編譯應用程序的頂級項之後,ASP.NET 將根據需要編譯文件夾、頁和其他項。 下表描述編譯 ASP.NET 文件夾和項的順序。
Item |
Description |
---|---|
App_LocalResources |
如果包含被請求項的文件夾包含 App_LocalResources 文件夾,則編譯本地資源文件夾的內容並將其鏈接到全局資源程序集。 |
各個網頁(.aspx 文件)、用戶控件(.ascx 文件)、HTTP 處理程序(.ashx 文件)和 HTTP 模塊(.asmx 文件) |
根據需要編譯並鏈接到本地資源程序集和頂級程序集。 |
主題、主控頁、其他源文件 |
在編譯引用頁時編譯那些頁所引用的各個主題、主控頁和其他源代碼文件的外觀文件。 |
編譯後的程序集緩存在服務器上並在後續請求時被重用,並且只要源代碼未更改,就會在應用程序重新啓動之間得到保留。
由於應用程序在第一次請求時進行編譯,所以對應用程序的初始請求所花的時間會明顯長於後續請求。 可以預編譯應用程序以減少第一次請求所需的時間。 有關更多信息,請參見 如何:預編譯 ASP.NET 網站。
Application Restarts(應用程序重新啓動的次數)
修改 Web 應用程序的源代碼將導致 ASP.NET 把源文件重新編譯爲程序集。 當修改應用程序中的頂級項時,應用程序中引用頂級程序集的其他所有程序集也會被重新編譯。
此外,修改、添加或刪除應用程序的已知文件夾中的某些類型的文件將導致應用程序重新啓動。 下列操作將導致應用程序重新啓動:
-
添加、修改或刪除應用程序的 Bin 文件夾中的程序集。
-
添加、修改或刪除 App_GlobalResources 或 App_LocalResources 文件夾中的本地化資源。
-
添加、修改或刪除應用程序的 Global.asax 文件。
-
添加、修改或刪除 App_Code 目錄中的源代碼文件。
-
添加、修改或刪除配置文件配置。
-
添加、修改或刪除 App_WebReferences 目錄中的 Web 服務引用。
-
添加、修改或刪除應用程序的 Web.config 文件。
當應用程序需要重新啓動時,ASP.NET 將在重新啓動應用程序域和加載新的程序集之前,從現有應用程序域和舊的程序集中爲所有掛起的請求提供服務。
ASP.NET 應用程序生命週期可通過 IHttpModule 類進行擴展。 ASP.NET 包含若干實現 IHttpModule 的類,如 SessionStateModule 類。 您還可以自行創建實現 IHttpModule 的類。
如果嚮應用程序添加模塊,模塊本身會引發事件。通過使用 modulename_eventname 約定,應用程序可以在 Global.asax 文件中預訂這些事件。 例如,若要處理 FormsAuthenticationModule 對象引發的 Authenticate 事件,可以創建一個名爲 FormsAuthentication_Authenticate 的處理程序。
默認情況下,ASP.NET 中會啓用 SessionStateModule 類。 所有會話事件自動命名爲 Session_event,如 Session_Start。 每次創建新會話時都會引發 Start 事件。 有關更多信息,請參見ASP.NET 會話狀態概述。