在ASP.NET中使用静态变量而不是Application状态

tes*_*icg 17 c# asp.net static state

我在ASP.NET中使用静态变量而不是Application状态,我想知道这是否是正确的方法:

[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);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我使用自动创建的Global.asax(和代码隐藏)文件.我添加了一些静态变量和方法.以这种方式我可以使用它们:

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

这是正确的方式还是我应该创建新的类而不是现有的Global?如果我要创建新课程,我该怎么做呢?

Ari*_*tos 20

微软说的话

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

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

我的经验

静态变量和应用程序状态之间的主要区别在于,应用程序状态在所有线程和池中是相同的,但静态仅在每个池中相同.

在新的测试之后,我看到Application状态变量与静态变量相同,并且它们仅引用应用程序上的静态变量,并且它们仅出于兼容性原因而存在,如microsoft所说

如果您有4个池运行您的站点(Web园),那么您有4组不同的静态内存.

你的代码

关于您的代码,您尝试访问dictionarry数据的方式存在错误,并且您将在真实网络中遇到错误.代码的这一部分是锁定完整字典的变量,但不能锁定您在使用它时要进行的更改.

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

例如,正确的方法是锁定添加/删除的所有操作,直到完成为止.

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;
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

从当你操作应用状态数据另一方面,你需要用全局的它锁Application.Lock();Application.UnLock();例如

Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"])+1;
Application.UnLock();
Run Code Online (Sandbox Code Playgroud)

最后得出一些结论:

避免应用程序状态,只需在代码中使用静态变量.