IIS 5.0 和 6.0 的 ASP.NET 應用程式生命週期概觀
更新:2007 年 11 月
本主題概述 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 就不會收到要求。了解這項特性對使用 ASP.NET 驗證的應用程式而言是很重要的。例如,因為 .htm 檔通常不會對應至 ASP.NET,所以 ASP.NET 不會對 .htm 檔執行驗證或授權檢查。因此,即使檔案只包含靜態內容,如果您想要 ASP.NET 檢查驗證,請使用對應至 ASP.NET 的副檔名 (像是 .aspx) 建立檔案。
注意事項:
如果您建立服務特定副檔名的自訂處理常式,就必須將副檔名對應至 IIS 中的 ASP.NET,並且也要在應用程式的 Web.config 檔中註冊處理常式。如需詳細資訊,請參閱 HTTP 處理常式和 HTTP 模組概觀。
|
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 會改為建立衍生自 HttpApplication 類別的 Global.asax 類別執行個體,然後使用衍生的類別代表應用程式。
注意事項:
當第一次在應用程式中要求 ASP.NET Web 網頁或處理序時,就會建立新的 HttpApplication 執行個體。然而,若要讓效能最佳化,多重處理序可能會重複使用 HttpApplication 執行個體。
當建立 HttpApplication 的執行個體時,也會建立任何設定的模組。例如,如果應用程式設定為執行這項動作,ASP.NET 就會建立 SessionStateModule 模組。在建立所有設定的模組後,就會呼叫 HttpApplication 類別的 Init 方法。 下列圖表說明這項關係: |
HttpApplication 管線會處理這項要求。 |
當處理要求時,HttpApplication 類別會執行下列事件。這些事件對擴充 HttpApplication 類別的開發人員特別有用。
|
生命週期事件和 Global.asax 檔
在應用程式生命週期期間,應用程式會引發能夠處理的事件,並且呼叫能夠覆寫的特定方法。若要處理應用程式事件或方法,您可以在應用程式根目錄中建立名為 Global.asax 的檔案。
如果您建立 Global.asax 檔,ASP.NET 會將其編譯為衍生自 HttpApplication 類別的類別,然後使用衍生的類別代表應用程式。
HttpApplication 執行個體一次只會處理一個要求。因為您不需要在應用程式類別中鎖定要存取的非靜態成員,所以能夠簡化應用程式事件處理。這也可以讓您將要求特定資料儲存在應用程式類別的非靜態成員中。例如,您可以在 Global.asax 檔中定義屬性,然後將要求特定值指派給它。
ASP.NET 會使用命名規範 Application_event (例如,Application_BeginRequest),自動將應用程式事件繫結至 Global.asax 檔案中的處理常式。這類似 ASP.NET Web 網頁方法會自動繫結至事件的方式,例如網頁的 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 類別的每個執行個體都會呼叫一次。 |
|
在終結應用程式執行個體之前呼叫。您可以使用這個方法手動釋放任何 Unmanaged 資源。如需詳細資訊,請參閱清除 Unmanaged 資源。 |
|
Application_End |
在卸載應用程式之前,應用程式的每個存留期都呼叫一次。 |
編譯生命週期
第一次要求應用程式時,ASP.NET 就會按特定的順序編譯應用程式項目。第一批要編譯的項目稱為最上層項目。在第一次要求後,只有相依性變更時,才會重新編譯最上層項目。下表將說明 ASP.NET 最上層項目的編譯順序。
項目 |
描述 |
---|---|
App_GlobalResources |
編譯應用程式的全域資源,而且會建置資源組件。應用程式 Bin 資料夾中的任何組件都會連結至此資源組件。 |
App_WebResources |
建立並編譯 Web 服務的 Proxy 型別。產生的 Web 參考組件會連結至資源組件 (如果它存在的話)。 |
Web.config 檔中定義的設定檔屬性 |
如果設定檔屬性是在應用程式的 Web.config 檔中定義,就會產生含有設定檔物件的組件。 |
App_Code |
建置原始程式碼檔,而且會建立一個或多個組件。所有程式碼組件和設定檔組件都會連結至資源和 Web 參考組件 (如果有的話)。 |
Global.asax |
編譯應用程式物件並連結至所有之前產生的組件。 |
當應用程式的最上層項目都編譯完成後,ASP.NET 就會視需要編譯資料夾、頁面和其他項目。下表將說明 ASP.NET 資料夾和項目的編譯順序。
項目 |
描述 |
---|---|
App_LocalResources |
如果內含所要求項目的資料夾含有 App_LocalResources 資料夾,就會編譯本機資源資料夾的內容並連結至全域資源組件。 |
個別的 Web 網頁 (.aspx 檔)、使用者控制項 (.ascx 檔)、HTTP 處理常式 (.ashx 檔) 和 HTTP 模組 (.asmx 檔) |
視需要編譯並連結至本機資源組件和最上層組件。 |
佈景主題、主版頁面和其他原始程式檔 |
當參考的頁面編譯後,就會編譯頁面所參考之個別佈景主題、主版頁面和其他原始程式檔的面板檔案。 |
在伺服器上會快取已編譯的組件以及在後續要求時重複使用,而且只要原始程式碼未變更就會保留至應用程式重新啟動。
由於應用程式是在第一次要求時編譯,所以應用程式的初始要求明顯會比後續要求花費較長的時間。您可以先行編譯應用程式,以減少第一次要求所需的時間。如需詳細資訊,請參閱HOW TO:先行編譯 ASP.NET 網站。
應用程式重新啟動
修改 Web 應用程式的原始程式碼會讓 ASP.NET 將原始程式檔重新編譯成組件。當您修改應用程式中的最上層項目時,應用程式中所有其他參考最上層組件的組件也會一併重新編譯。
此外,在應用程式的已知資料夾內修改、加入或刪除某些檔案類型將會導致應用程式重新啟動。下列動作將會導致應用程式重新啟動:
從應用程式的 Bin 資料夾中加入、修改或刪除組件。
從 App_GlobalResources 或 App_LocalResources 資料夾中加入、修改或刪除當地語系化資源。
加入、修改或刪除應用程式的 Global.asax 檔。
在 App_Code 目錄中加入、修改或刪除原始程式碼檔。
加入、修改或刪除設定檔組態。
在 App_WebReferences 目錄中加入、修改或刪除 Web 服務參考。
加入、修改或刪除應用程式的 Web.config 檔。
當要求應用程式重新啟動時,ASP.NET 會先服務現有應用程式定義域和舊組件中的所有暫止要求,然後再重新啟動應用程式定義域並載入新的組件。
HTTP 模組
您可以經由 IHttpModule 類別擴充 ASP.NET 應用程式生命週期。ASP.NET 會包含實作 IHttpModule 的幾個類別,例如 SessionStateModule 類別。您也可以建立實作 IHttpModule 類別。
如果您將模組加入應用程式,模組本身就能夠引發事件。應用程式可以使用慣例 modulename_eventname,在 Global.asax 檔案中訂閱這些事件。例如,若要處理 FormsAuthenticationModule 物件引發的 Authenticate 事件,您可以建立名為 FormsAuthentication_Authenticate 的處理常式。
在 ASP.NET 中,預設為啟用 SessionStateModule 類別。所有工作階段事件都會自動連線為 Session_event,例如 Session_Start。每次建立新的工作階段時都會引發 Start 事件。如需詳細資訊,請參閱ASP.NET 工作階段狀態概觀。