Utilizzo di variabili statiche anziché di stato dell’applicazione in ASP.NET

Pianifico di utilizzare variabili statiche invece di stato dell’applicazione in ASP.NET e mi chiedo se questo è l’approccio corretto:

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

Come puoi vedere, utilizzo automaticamente il file Global.asax (e code behind). Ho aggiunto alcune variabili e metodi statici. Posso usarli dopo in questo modo:

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

È questo il modo giusto o dovrei creare una nuova class invece di Global esistente? Se dovessi creare una nuova class, come posso farlo e dove?

Che cosa dice Microsoft

ASP.NET include lo stato dell’applicazione principalmente per la compatibilità con ASP classico in modo che sia più semplice migrare le applicazioni esistenti in ASP.NET. Si consiglia di archiviare i dati in membri statici della class dell’applicazione anziché nell’object Application. Ciò aumenta le prestazioni poiché è ansible accedere a una variabile statica più rapidamente di quanto non sia ansible accedere a un elemento nel dizionario dell’applicazione.

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

La mia esperienza

La differenza principale tra le variabili statiche e lo stato dell’applicazione è che lo stato dell’applicazione è lo stesso per tutti i thread e i pool, ma lo statico è lo stesso solo per pool.

Dopo i nuovi test vedo che le variabili di stato dell’applicazione sono le stesse delle variabili statiche e fanno semplicemente riferimento a una variabile statica sull’applicazione e esistono solo per ragioni di compatibilità, come afferma microsoft

Se hai 4 piscine che gestiscono il tuo sito (web garden) allora hai 4 set di memoria statica diversa.

Il tuo codice

Riguardo al tuo codice, hai un bug per il modo in cui provi ad accedere ai tuoi dati di dictionarry, e avrai degli errori nel web reale. Questa parte del codice blocca la variabile del dizionario completo, ma non blocca le modifiche che intendi apportare quando lo utilizzi.

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

L’approccio corretto è bloccare tutte le azioni di aggiunta / rimozione fino a quando non hai fatto, per esempio.

 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; } ... } 

D’altra parte quando si manipolano i dati sullo stato dell’applicazione è necessario utilizzare il blocco globale di Application.Lock(); e Application.UnLock(); per esempio

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

Per chiudere con un risultato:

Evita lo stato dell’applicazione e usa solo variabili statiche sul tuo codice.