我在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);
}
...
}
如您所见,我使用自动创建的Global.asax(和代码隐藏)文件。我添加了一些静态变量和方法。我可以用这种方式使用它们:
[some .cs file]
foreach(KeyValuePair<string, object> dictItem in Global.CacheItems)
{
...
这是正确的方法还是我应该创建新的课程而不是现有的全球课程?如果我应该创建新课程,我该怎么做?在哪里?
答案 0 :(得分:20)
ASP.NET包括主要用于兼容的应用程序状态 经典ASP,以便更容易地迁移现有的应用程序 ASP.NET。建议您将数据存储在静态成员中 应用程序类而不是Application对象。这个 提高性能,因为您可以更快地访问静态变量 您可以访问应用程序词典中的项目。
参考:http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607
静态变量和应用程序状态之间的主要区别在于,所有线程和池的Application状态是相同的,但每个池的静态是相同的。
在新测试之后,我看到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;} }
}
正确的方法是锁定所有添加/删除操作,直到完成为止,例如。
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;
}
...
}
另一方面,当您在应用程序状态下操作数据时,您需要使用 global 锁定Application.Lock();
和Application.UnLock();
,例如
Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"])+1;
Application.UnLock();
结束时得出一些结论:
避免应用程序状态,只需在代码中使用静态变量。