從HttpApplication派生的Global 類有很多用處包括管理應用程序狀態和請求狀態
Visual StudioNET 創建的globalasax文件為每個web 應用程序生成一個從HttpApplication類派成的Global類這個類包含很多事件處理程序例如Application_Start和 Session_Start
或許有人認為每個web應用程序只有一個Global類的實例事實上在大多數應用程序框架中代表Application的對象都是singleton – 就是說只有一個實例存在我們也知道ASPNET運行時只有在應用程序開始的時候才調用Application_Start事件處理方法所有這些好像都在暗示在我們的ASPNET Web應用程序中只有一個Global對象的實例但是所有這些確確實實是誤導!
ASPNET 運行時(ASPNET runtime以下簡稱運行時)維護了一個HttpApplication對象池當一個請求進來的時候運行時從該池中取出一個HttpApplication對象來服務於當前請求該HttpApplication對象一直和該請求相關聯且只和該請求相關聯直到請求被處理完畢當請求完成後運行時把該對象歸還到池中稍後會從池中再次取出去服務於另外的請求但一個請求每次只能和某一個HttpApplication對象相關聯
Application State VS Request State
Application對象(HttpApplicationState 類型譯者按Application對象是HttpApplication類的一個屬性是web應用程序全局唯一的web應用程序第一次有請求進來的時候創建的) 是我們在web應用程序內保存全局信息的地方Application對象是一個很方便的保存全局信息的地方例如保存數據庫的連接字符串
private void Page_Load(object sender SystemEventArgs e)
{
string connectionString = Application[ConnectionString]ToString();
}
你也可以在HttpApplication類中聲明靜態成員變量來保存應用程序狀態信息例如上例中的數據庫連接字符串可以用如下方式保存
public class Global : SystemWebHttpApplication
{
public static readonly string ConnectionString = connection information;
}
可以在ASPNET代碼的任何地方訪問該靜態成員變量例如:string connectionString = GlobalConnectionString;
非常重要的一點是如果你想讓該字符串可以全局范圍內被訪問到則該字符串必須聲明為靜態成員變量(你也可以創建一個靜態的屬性)
相反如果你在Global類型使用一般成員變量(非靜態)則只能用來保存請求狀態舉個例子來說明下面的代碼將在調試窗口中輸出所有請求的處理時間(毫秒)
public class Global : SystemWebHttpApplication
{
protected DateTime beginRequestTime;
protected void Application_BeginRequest(Object sender EventArgs e)
{
beginRequestTime = DateTimeNow;
}
protected void Application_EndRequest(Object sender EventArgs e)
{
string messageFormat = Elapsed request time (ms) = {};
TimeSpan diffTime = DateTimeNow beginRequestTime;
TraceWriteLine(
StringFormat(messageFormat diffTimeTotalMilliseconds ) );
}
}
好現在讓我們回到上面關於保存應用程序狀態的話題那個方法更好的呢在Application對象中保存對象的引用還是在Global類中聲明靜態成員或屬性?各種方式各有優劣在Global類中保存全局靜態成員可以使你的數據訪問具有強類型不象Application對象你不需要進行類型轉換下面的代碼說明了它們的區別
DataSet cachedData = (DataSet)Application[MyDataSet];
string myString = Application[MyString]ToString();
DataSet cachedData = GlobalMyDataSet;
string myString = GlobalMyString;
強類型使你的的代碼更加清晰和強壯在應用程序性能要求比較高的情況下這種方式可以避免運行時類型轉換帶來的性能損失如果你保存的是值類型的數據強類型還可以避免裝箱(boxing)和卸箱(unboxing)所帶來的性能損失另外Application對象還有因為線程同步造成的鎖定所帶來的性能上問題如果你的全局數據只初始化一次再也不會改變使用Global類中的靜態成員可以避免鎖定帶來的性能損失但如果你采用了這種方式強烈推薦你使用訪問器(屬性)以保證該變量是只讀的如果你既要讀又要寫在Global類中的靜態成員變量記住要保證線程安全Application對象通過獲取讀寫鎖已經內在的提供了線程安全保證
比較安全的初始化全局靜態成員變量的地方是在Application_Start事件處理程序中即使全局范圍有很多個Global對象的實例運行時只會在Global對象第一次創建的時候調用Application_Start事件處理程序
比較理想的初始化請求狀態變量的地方是Application_BeginRequest請求狀態變量一般情況下不需要線程安全因為每個Global對象在同一時刻只服務於一個請求
From:http://tw.wingwit.com/Article/program/net/201311/12735.html