Problema con HttpRuntime.Cache

Sto usando il seguente codice .net per aggiungere oggetti alla cache:

public static void Add(string key, T dataToCache) { try { ApplicationLog.Instance.WriteInfoFormat("Inserting item with key {0} into Cache...", key); HttpRuntime.Cache.Insert( key, dataToCache, null, DateTime.Now.AddDays(7), System.Web.Caching.Cache.NoSlidingExpiration); } catch (Exception ex) { ApplicationLog.Instance.WriteException(ex); } } 

e qui è il mio codice per recuperare i valori dalla cache:

 public static T Get(string key) { try { if (Exists(key)) { ApplicationLog.Instance.WriteInfoFormat("Retrieving item with key {0} from Cache...", key); return (T)HttpRuntime.Cache[key]; } else { ApplicationLog.Instance.WriteInfoFormat("Item with key {0} does not exist in Cache.", key); return default(T); } } catch(Exception ex) { ApplicationLog.Instance.WriteException(ex); return default(T); } } public static bool Exists(string key) { bool retVal = false; try { retVal= HttpRuntime.Cache[key] != null; } catch (Exception ex) { ApplicationLog.Instance.WriteException(ex); } return retVal; } 

Ma trovo che dopo ogni 2 minuti o giù di lì, il valore dell’object memorizzato nella cache viene impostato su null risultante nel tirare nuovamente quel valore dal database.

Cosa mi manca qui?

Quando dici ogni due minuti il ​​valore inserito è impostato su null, significa solo l’object che ti interessa o ogni singolo elemento nella cache?

Lo chiedo perché la cache esiste solo finché l’applicazione è in esecuzione. Se l’applicazione viene riavviata, la cache scompare. Questo spiegherebbe il comportamento se tutto va via ogni 2 minuti. In questo caso hai un altro problema: perché l’applicazione si riavvia ogni 2 minuti.

Se si tratta solo di alcuni elementi, potrebbe trattarsi di un problema di memoria. La cache si pulisce in risposta alla scarsa memoria. Credo che ci sia un modo per impostare la priorità sui valori inseriti. Ma questo dovrebbe essere un problema solo quando hai poca memoria.

Se questo non risolve ancora il tuo problema, c’è un modo per scoprire perché un object viene rimosso. È spiegato qui .

Beh, prima di tutto il tuo accesso non è sincronizzato, quindi è una grande fonte di problemi. La lettura da HttpRuntime Cache è garantita per essere thread-safe, quindi dovresti davvero provare a leggere il tuo articolo come primo passo su ogni operazione di cache.

Tra controllare se Exists e effettivamente recuperare l’object possono accadere molte cose (come il tuo object non esserci più). Dovresti ottenere un handle dell’articolo che stai cercando e, se non lo è, fornire inserto sicuro per i thread recuperandolo dal tuo archivio dati persistente.

Quindi la tua logica Add entrerebbe nel tuo Get IF se i dati non ci sono. Non c’è nulla di fondamentalmente sbagliato nel fornire una logica di Add separata e si dovrebbe misurare il costo di colpire il database più volte rispetto al blocco di ulteriori richieste per quel particolare pezzo di dati.

 T GetT(string key) { T item = (cache.Get(key) as T); if (item == null) { lock (yourSyncRoot) { // double check it here item = (cache.Get(key) as T); if (item != null) return item; item = GetMyItemFromMyPersistentStore(key); // db? if (item == null) return null; string[] dependencyKeys = {your, dependency, keys}; cache.Insert(key, item, new CacheDependency(null, dependencyKeys), absoluteExpiration, slidingExpiration, priority, null); } } return item; } 

A seconda della tua politica di scadenza, i tuoi dati saranno conservati in memoria e ti forniranno un accesso veloce e sincronizzato, ma come ho detto, misuralo e adattalo alle tue esigenze. Nella logica aziendale dopo aver aggiornato il tuo articolo e averlo salvato correttamente nel tuo archivio persistente, rimuovilo dalla cache e la prossima chiamata al tuo Get lo recupererà di nuovo.

Potrebbe essere perché la memoria sta per esaurirsi, la cache eliminerà automaticamente gli elementi nella cache quando la memoria sta diventando scarsa, C’è un parametro opzionale per impostare la priorità degli elementi nella cache se vuoi che un elemento venga cancellato prima di un altro.