Usar variables estáticas en lugar de estado de aplicación en ASP.NET

Planeo usar variables estáticas en lugar de estado de aplicación en ASP.NET y me pregunto si este es el enfoque correcto:

[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 cacheItems = new Dictionary(); private static object locker = new object(); public static Dictionary CacheItems { get { lock (locker) { return cacheItems; } } set { lock (locker) { cacheItems = value; } } } public static void RemoveCacheItem(string key) { cacheItems.Remove(key); } ... } 

Como puede ver, utilizo el archivo Global.asax (y el código detrás) creado automáticamente. He agregado algunas variables y métodos estáticos. Puedo usarlos después de esta manera:

 [some .cs file] foreach(KeyValuePair dictItem in Global.CacheItems) { ... 

¿Es este el camino correcto o debería crear una nueva clase en lugar de Global existente? Si debería crear una nueva clase, ¿cómo puedo hacer eso y dónde?

Lo que dice Microsoft

ASP.NET incluye el estado de la aplicación principalmente para la compatibilidad con ASP clásico, por lo que es más fácil migrar las aplicaciones existentes a ASP.NET. Se recomienda almacenar datos en miembros estáticos de la clase de aplicación en lugar de en el objeto Aplicación. Esto aumenta el rendimiento porque puede acceder a una variable estática más rápido de lo que puede acceder a un elemento en el diccionario de la aplicación.

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

Mi expiriencia

La diferencia principal entre las variables estáticas y el estado de la aplicación es que el estado de la aplicación es el mismo en todos los subprocesos y grupos, pero la estática es la misma solo por grupo.

Después de nuevas pruebas, veo que las variables de estado de la Aplicación son las mismas que las variables estáticas, y solo hacen referencia a una variable estática en la aplicación, y solo existen por razones de compatibilidad, como dice microsoft.

Si tiene 4 pools ejecutando su sitio (web garden), entonces tiene 4 conjuntos de diferentes memorias estáticas.

Tu codigo

Acerca de su código, tiene errores por la forma en que trata de acceder a sus datos del dictionarry, y va a tener errores en la web real. Esta parte del código bloquea la variable del diccionario completo pero no bloquea el cambio que va a realizar cuando lo use.

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

El enfoque correcto es bloquear todas las acciones de agregar / eliminar hasta que termine, por ejemplo.

 private static Dictionary cacheItems = new Dictionary(); private static object locker = new object(); public Dictionary CacheItems { get{ return cacheItems; } set{ cacheItems = value;} } SomeFunction() { ... lock(locker) { CacheItems["VariableName"] = SomeObject; } ... } 

Por otro lado, cuando manipula datos en el estado de la aplicación, necesita usar el locking global Application.Lock(); y Application.UnLock(); por ejemplo

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

Para cerrar con un resultado:

Evite el estado de la aplicación y simplemente use variables estáticas en su código.