2010-04-07 49 views
2

我正在處理一個現有的項目,由另一個編碼器設置。我在理解頁面之間的狀態維護方面遇到了一些麻煩。有一個類庫有一些幫助對象。大多數情況下,這些對象僅用於靜態方法,很少實例化或繼承。靜態變量以某種方式維護狀態?

這是我正在測試的示例類。

public sealed class Application 
{ 
    public static string Test; 
} 

現在,當我運行像在基類中我的網頁下面,我希望得到的結果是「1:2:測試」所有的時間(注意,「1」爲空),但只有在第一次運行時纔會這樣。然後每次都是「1:測試2:測試」。不知何故,它維護頁面之間的靜態變量的狀態和正在刷新?

Response.Write("1:" + SharedLibrary.Application.Test); 

SharedLibrary.Application.Test = "Test"; 

Response.Write(" 2:" + SharedLibrary.Application.Test); 

我需要創建更多這樣的類,但要理解爲什麼這是發生在第一位。

非常感謝

+0

「頁面和被刷新」是否意味着你在ASP.Net中使用這個類庫或什麼? – Earlz 2010-04-07 01:03:06

+2

這是正確的,它是一個ASP.Net App – gfoley 2010-04-07 01:07:03

回答

5

正如其他人聲明的那樣:在Asp.Net應用程序中聲明爲靜態變量的任何內容都會保持其相同的值,直到更改爲止。

這裏是你真正需要知道:

  • 該值將丟失時(不如果,但)的應用程序池回收。通常這種情況每天都會發生,但如果內存不足或發生崩潰也會發生這種情況。

  • 該值將被所有請求併發訪問,即多個用戶等。

所以,如果這個值是例如計數器:

Response.Write("1:" + SharedLibrary.Application.Test); 
SharedLibrary.Application.Test = int.Parse(SharedLibrary.Application.Test) + 1; 
Response.Write(" 2:" + SharedLibrary.Application.Test); 

您可能會發現意想不到的輸出如 「1:53 2:55」。這將是由幾個瀏覽器同時執行測試頁面的結果。

  • 當您第一次訪問或創建類的實例時,靜態變量總是初始化。他們都初始化。所以如果你有一個很大的「桶」或「靜態變量」(我稱之爲設計不當的輔助類「桶」),並且你只使用其中的一個,那麼每個內存仍然會被分配。

  • 最後,這個值是從來沒有垃圾收集。所以如果你在靜態變量中放置一個大的項目,那麼只要進程存在,它就會消耗這個內存。 (請不要把一次性資源,即SqlConnection的,在那裏。)

+0

+1爲「設計糟糕」的參考。 – VoidDweller 2010-04-07 02:28:11

2

在ASP.Net,作爲服務器正在運行(只有少數例外)靜態變量保持自己的狀態,只要。如果您希望有一個靜態變量在頁面刷新時不保持其狀態(請參閱:HTTP請求),請圍繞HttpContext類包裝一個屬性。

0

大多數Web應用程序/框架實際上保持代碼在調用之間運行,並且只在服務器或工作人員關閉時停止代碼。 PHP在這裏是一個奇怪的,而不是其他人。

0

靜態類靜態成員一旦加載(訪問)保留在內存中直到加載它的應用,是卸載。所以,當你的頁面請求訪問靜態成員SharedLibrary.Application.Test每個請求正在訪問相同的內存位置。

MSDN文章Static Classes and Static Class Members會給你一些額外的見解。

當你說你需要創建更多這樣的課程時,你希望這些課程做什麼?

+0

基本上只是全局變量類,它們都將作爲靜態變量存在於不同的類中,因爲我們有幾種類型的全局變量。有些是從數據庫中提取的,有些是常量,有些是基於客戶端計算的。 – gfoley 2010-04-07 03:41:08

+0

謹慎使用它們,靜態提供可預測的行爲,但如果沒有經過深思熟慮可能會出乎意料。基於客戶端計算 - 這聽起來適合會話變量。數據庫 - 你真的需要減少到連接嗎?使用緩存可能會得到更好的優化。常量 - 好吧,我會給你常量。 – VoidDweller 2010-04-10 17:19:49