HttpApplication类及派生的Global类
從HttpApplication派生的Global?類有很多用處,包括管理應(yīng)用程序狀態(tài)和請求狀態(tài)
Visual Studio.NET?創(chuàng)建的global.asax文件為每個web?應(yīng)用程序生成一個從HttpApplication類派成的Global類,這個類包含很多事件處理程序,例如Application_Start和?Session_Start.
?
???????或許有人認為每個web應(yīng)用程序只有一個Global類的實例。事實上,在大多數(shù)應(yīng)用程序框架中,代表”Application”的對象都是singleton –?就是說只有一個實例存在。我們也知道ASP.NET運行時只有在應(yīng)用程序開始的時候才調(diào)用Application_Start事件處理方法。所有這些好像都在暗示,在我們的ASP.NET Web應(yīng)用程序中只有一個Global對象的實例,但是所有這些確確實實是誤導!
???????ASP.NET?運行時(ASP.NET runtime,以下簡稱“運行時“)維護了一個HttpApplication對象池。當一個請求進來的時候,運行時從該池中取出一個HttpApplication對象來服務(wù)于當前請求,該HttpApplication對象一直和該請求相關(guān)聯(lián),且只和該請求相關(guān)聯(lián),直到請求被處理完畢。當請求完成后,運行時把該對象歸還到池中,稍后會從池中再次取出去服務(wù)于另外的請求?–?但一個請求每次只能和某一個HttpApplication對象相關(guān)聯(lián)。
Application?State?vs?Request?State
Application對象(HttpApplicationState?類型,譯者按:Application對象是HttpApplication類的一個屬性,是web應(yīng)用程序全局唯一的,web應(yīng)用程序第一次有請求進來的時候創(chuàng)建的)?是我們在web應(yīng)用程序內(nèi)保存全局信息的地方,Application對象是一個很方便的保存全局信息的地方,例如保存數(shù)據(jù)庫的連接字符串:?
private?void?Page_Load(object?sender, System.EventArgs e)
{
?????????string?connectionString =
???????????????????Application["ConnectionString"].ToString();
. . . .
}
???????你也可以在HttpApplication類中聲明靜態(tài)成員變量來保存應(yīng)用程序狀態(tài)信息,例如,上例中的數(shù)據(jù)庫連接字符串可以用如下方式保存。
???????public?class?Global : System.Web.HttpApplication
???????{
??????????????public?static
?????????????????????readonly?string?ConnectionString = "connection information";
??????????????. . .???
???????}
可以在ASP.NET代碼的任何地方訪問該靜態(tài)成員變量,例如
string?connectionString = Global.ConnectionString;
???????非常重要的一點是,如果你想讓該字符串可以全局范圍內(nèi)被訪問到,則該字符串必須聲明為靜態(tài)成員變量(你也可以創(chuàng)建一個靜態(tài)的屬性)。
?
相反,如果你在Global類型使用一般成員變量(非靜態(tài)),則只能用來保存請求狀態(tài),舉個例子來說明,下面的代碼將在調(diào)試窗口中輸出所有請求的處理時間(毫秒)
???
public?class?Global : System.Web.HttpApplication
{
???????protected?DateTime beginRequestTime;
???????protected?void?Application_BeginRequest(Object sender, EventArgs e)
???????{
??????????????beginRequestTime = DateTime.Now;
???????}
???????protected?void?Application_EndRequest(Object sender, EventArgs e)
???????{
??????????????string?messageFormat = "Elapsed request time (ms) = {0}";
??????????????TimeSpan diffTime = DateTime.Now - beginRequestTime;
??????????????Trace.WriteLine(
?????????????????????String.Format(messageFormat, diffTime.TotalMilliseconds???????) );???????????????????
???????}
???????. . .
}
?好,現(xiàn)在讓我們回到上面關(guān)于保存應(yīng)用程序狀態(tài)的話題。那個方法更好的呢:在Application對象中保存對象的引用,還是在Global類中聲明靜態(tài)成員或?qū)傩?#xff1f;各種方式各有優(yōu)劣。
???????在Global類中保存全局靜態(tài)成員可以使你的數(shù)據(jù)訪問具有強類型,不象Application對象,你不需要進行類型轉(zhuǎn)換,下面的代碼說明了它們的區(qū)別:
DataSet cachedData = (DataSet)Application[“MyDataSet”];
string?myString = Application[“MyString”].ToString();
?
DataSet cachedData = Global.MyDataSet;
string?myString??= Global.MyString;
?
???????強類型使你的的代碼更加清晰和強壯,在應(yīng)用程序性能要求比較高的情況下,這種方式可以避免運行時類型轉(zhuǎn)換帶來的性能損失。如果你保存的是值類型的數(shù)據(jù),強類型還可以避免裝箱(boxing)和卸箱(unboxing)所帶來的性能損失。另外,Application對象還有因為線程同步造成的鎖定所帶來的性能上問題。如果你的全局數(shù)據(jù)只初始化一次,再也不會改變,使用Global類中的靜態(tài)成員可以避免鎖定帶來的性能損失。但,如果你采用了這種方式,強烈推薦你使用訪問器(屬性),以保證該變量是只讀的。如果你既要讀又要寫在Global類中的靜態(tài)成員變量,記住要保證線程安全。Application對象通過獲取讀寫鎖已經(jīng)內(nèi)在的提供了線程安全保證。
???????比較安全的初始化全局靜態(tài)成員變量的地方是在Application_Start事件處理程序中。即使全局范圍有很多個Global對象的實例,運行時只會在Global對象第一次創(chuàng)建的時候調(diào)用Application_Start事件處理程序。
???????比較理想的初始化請求狀態(tài)變量的地方是Application_BeginRequest,請求狀態(tài)變量一般情況下不需要線程安全,因為每個Global對象在同一時刻只服務(wù)于一個請求
轉(zhuǎn)載于:https://www.cnblogs.com/JoinZhang/archive/2010/08/12/1798082.html
總結(jié)
以上是生活随笔為你收集整理的HttpApplication类及派生的Global类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PL/SQL Developer 9 注
- 下一篇: 改造MUC实现Openfire群