簡體   English   中英

在 ASP.NET 中使用靜態變量而不是應用程序狀態

[英]Using static variables instead of Application state in ASP.NET

我打算在 ASP.NET 中使用靜態變量而不是應用程序狀態,並且想知道這是否是正確的方法:

[Global.asax.cs]

...

public class Global : System.Web.HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup

    }

    ...

    private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
    private static object locker = new object();

    public static Dictionary<string, object> CacheItems
    {
        get
        {
            lock (locker)
            {
                return cacheItems;
            }
        }

        set
        {
            lock (locker)
            {
                cacheItems = value;
            }
        }
    }

    public static void RemoveCacheItem(string key)
    {
        cacheItems.Remove(key);
    }

    ...
}

如您所見,我使用自動創建的 Global.asax(和代碼隱藏)文件。 我添加了一些靜態變量和方法。 我可以以這種方式使用它們:

[some .cs file]
foreach(KeyValuePair<string, object> dictItem in Global.CacheItems)
{
    ...

這是正確的方法還是我應該創建新類而不是現有的全局? 如果我應該創建新班級,我該怎么做以及在哪里做?

微軟怎么說

ASP.NET 包含應用程序狀態主要是為了與經典 ASP 兼容,以便更輕松地將現有應用程序遷移到 ASP.NET。 建議您將數據存儲在應用程序類的靜態成員中,而不是應用程序對象中。 這會提高性能,因為您可以比訪問 Application 字典中的項目更快地訪問靜態變量。

參考:http ://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

我的經驗

靜態變量和應用程序狀態之間的主要區別在於,所有線程和池的應用程序狀態都相同,但靜態變量僅每個池相同。

經過新的測試后,我發現應用程序狀態變量與靜態變量相同,它們只是引用了應用程序上的靜態變量,它們只是出於兼容性原因而存在,正如微軟所說

如果您有 4 個池運行您的站點(網絡花園),那么您將擁有 4 組不同的靜態內存。

你的代碼

關於您的代碼,您嘗試訪問字典數據的方式存在錯誤,並且您將在真實網絡中遇到錯誤。 這部分代碼是鎖定完整字典的變量,但不鎖定您在使用它時將要進行的更改。

// this is not enough to manipulate your data !
public static Dictionary<string, object> CacheItems
{
    get { lock (locker) { return cacheItems; } }
    set { lock (locker) { cacheItems = value; } }
}

例如,正確的方法是鎖定所有添加/刪除操作,直到您完成為止。

private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
private static object locker = new object();
public Dictionary<string, object> CacheItems
{
    get{ return cacheItems; }
    set{ cacheItems = value; }
}

SomeFunction()
{
    ...
    lock(locker)
    {
        CacheItems["VariableName"] = SomeObject;
    }
    ...
}

另一方面,當您操作應用程序狀態數據時,您需要使用它的 全局 Application.Lock(); Application.UnLock(); 例如

Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"]) + 1;
Application.UnLock();

以一些結論結束:

避免應用程序狀態,只在代碼中使用靜態變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM