2012-09-24 15 views
7

Sto utilizzando uno HttpRuntime.Cache per archiviare un elenco di oggetti che accedono frequentemente attraverso le sessioni.Leggere l'elemento HttpRuntime.Cache in sola lettura

Io uso la seguente riga di codice per ottenere l'oggetto dalla cache:

List<chartData_Type> _chartData = 
      (List<chartData_Type>)HttpRuntime.Cache.Get("rollingMonth"); 

Ma, purtroppo, quando aggiorno il _chartData, aggiorna l'elemento memorizzato nella cache troppo.

Come posso ottenere semplicemente una copia dell'elemento memorizzato nella cache?

risposta

6

Questo è il modo in cui funziona perché .NET cache solo riferimento al puntatore di List. Non so se è chartData_Type il tipo di valore o il tipo di riferimento.

Se tipo di valore, è facile da usare:

List<chartData_Type> list = new List<chartData_Type>(_chartData); 

Ma se tipo di riferimento, si tratta di complicato, è necessario implementare DeepCopy metodo per la classe, poi fare DeepCopy per ogni oggetto in elenco.

DeepClone metodo:

public static class CloneHelper 
{ 
    public static T DeepClone<T>(T obj) 
    { 
     using (var ms = new MemoryStream()) 
     { 
      var formatter = new BinaryFormatter(); 
      formatter.Serialize(ms, obj); 
      ms.Position = 0; 

      return (T) formatter.Deserialize(ms); 
     } 
    } 
} 

Per poter utilizzare questo metodo, classe chartData_Type deve essere contrassegnato [Serializable]:

[Serializable] 
class chartData_Type 
{} 

Quindi, si può fare profondo clone manualmente:

var cloneChartData = _chartData.Select(d => 
             CloneHelper.DeepClone<chartData_Type>(d)) 
         .ToList(); 
+0

Mi chiedo se AppFabric o NCache risolverebbero questo problema. Ho chiesto questo in un'altra discussione: http://stackoverflow.com/questions/23546817/appfabric-ncache-will-these-solve-httpruntime-cache-objects-being-updated-by-r – DrGriff

1

Usa:

List<chartData_Type> list = new List<chartData_Type>(_chartData); 

Sarà copiare tutti gli elementi _chartData-list.

+0

Nota che questa sarà una copia profonda dell'oggetto, quindi dovrai fare su Se la cache e questa copia rimangono sincronizzati altrimenti ... OOOOOPS! –

+0

Forse una piccola spiegazione sul perché la sua copia stia aggiornando anche la versione cache. Otterrò il mio voto = P –

1

L'elenco è un tipo di riferimento e _chartData contiene l'indirizzo dell'oggetto originale memorizzato nella cache. Ecco perché quando aggiorni _chartData, aggiorna anche l'oggetto memorizzato nella cache. Se si desidera un oggetto separato, clonare l'oggetto memorizzato nella cache. Vedi sotto riferimento

http://www.codeproject.com/Articles/33364/ASP-NET-Runtime-Cache-Clone-Objects-to-Preserve-Ca

http://www.codeproject.com/Articles/45168/ASP-NET-Runtime-Cache-Clone-Objects-to-Preserve-Ca