18

我打算在 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)
{
    ...

这是正确的方法还是我应该创建新类而不是现有的全局?如果我应该创建新课程,我该怎么做?在哪里?

4

1 回答 1

20

微软怎么说

ASP.NET 包括应用程序状态,主要是为了与经典 ASP 兼容,以便更容易将现有应用程序迁移到 ASP.NET。建议您将数据存储在应用程序类的静态成员中,而不是应用程序对象中。这提高了性能,因为您可以比访问应用程序字典中的项目更快地访问静态变量。

参考: 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();

以一些结论结束:

避免应用程序状态,只在代码上使用静态变量。

于 2012-06-09T19:42:55.610 回答