我打算在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) { ...
这是正确的方法还是我应该创建新的类而不是现有的Global?如果我应该开设新课程,该怎么办?在哪里?
ASP.NET包括应用程序状态,主要是为了与经典ASP兼容,因此更容易将现有应用程序迁移到ASP.NET。建议将数据存储在应用程序类的静态成员中,而不是存储在Application对象中。这可以提高性能,因为访问静态变量的速度比访问应用程序字典中的项的速度更快。
参考:http : //support.microsoft.com/default.aspx?scid=kb;zh- CN;Q312607
静态变量和应用程序状态之间的主要区别在于,所有线程和池的应用程序状态都相同,但是仅每个池的静态状态是相同的。
经过新的测试后,我发现Application状态变量与静态变量相同,并且它们仅引用应用程序上的静态变量,并且出于兼容性原因而存在,如Microsoft所说。
如果您有4个运行站点的池(网络花园),则您有4套不同的静态内存。
关于您的代码,您尝试访问词典数据的方式存在错误,并且在实际网络中将出现错误。这部分代码锁定了完整Dictionary的变量,但不锁定您在使用时要进行的更改。
// 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.UnLock();
Application.Lock(); Application["PageRequestCount"] = ((int)Application["PageRequestCount"]) + 1; Application.UnLock();
最后得出一些结论:
避免应用程序状态,而只在代码上使用静态变量。