2013-08-12 11 views
10

Sono un neofita dei generici in C# e sto cercando di creare una memoria che altre parti del mio programma possano richiedere per modelli oggetti. L'idea era che se la mia classe cache ha l'oggetto, controlla la sua data e la restituisce se l'oggetto non è più vecchio di 10 min. Se è più vecchio di 10 minuti, scarica un modello aggiornato dal server online. Non ha l'oggetto lo scarica e lo restituisce.Come posso creare una classe che memorizza nella cache gli oggetti?

Ma ho qualche problema ad associare i miei oggetti con un DateTime, rendendolo tutto generico.

// model 
public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person(); 

     Cache c = new Cache(); 

     p = c.Get<Person>(p); 
    } 
} 

public class Cache 
{ 
    struct DatedObject<T> 
    { 
     public DateTime Time { get; set; } 
     public T Obj { get; set; } 
    } 

    List<DatedObject<T>> objects; 

    public Cache() 
    { 
     objects = new List<DatedObject<T>>(); 
    } 

    public T Get<T>(T obj) 
    { 
     bool found = false; 

     // search to see if the object is stored 
     foreach(var elem in objects) 
      if(elem.ToString().Equals(obj.ToString())) 
      { 
       // the object is found 
       found = true; 

       // check to see if it is fresh 
       TimeSpan sp = DateTime.Now - elem.Time; 

       if(sp.TotalMinutes <= 10) 
        return elem; 
      } 


     // object was not found or out of date 

     // download object from server 
     var ret = JsonConvert.DeserializeObject<T>("DOWNLOADED JSON STRING"); 

     if(found) 
     { 
      // redate the object and replace it in list 
      foreach(var elem in objects) 
       if(elem.Obj.ToString().Equals(obj.ToString())) 
       { 
        elem.Obj = ret; 
        elem.Time = DateTime.Now; 
       } 
     } 
     else 
     { 
      // add the object to the list 
      objects.Add(new DatedObject<T>() { Time = DateTime.Now, Obj = ret });     
     } 

     return ret; 
    } 
} 
+0

puoi fornire maggiori dettagli sul problema/errore nell'associare oggetti? probabilmente potresti provare la classe invece della struttura per 'DatedObject', e se non vuoi creare il tuo oggetto di classe, prova Tuple – Rex

+0

[Akavache] (https://github.com/github/Akavache) potrebbe valere la pena in. –

risposta

22

Partenza classe cache di memoria disponibile come parte del framework .NET http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

Avrai bisogno di aggiungere l'assembly System.RunTime.Caching come riferimento per l'applicazione. Quanto segue è una classe helper per aggiungere elementi e rimuoverli dalla cache.

using System; 
using System.Runtime.Caching; 

public static class CacheHelper 
{ 
    public static void SaveTocache(string cacheKey, object savedItem, DateTime absoluteExpiration) 
    { 
     MemoryCache.Default.Add(cacheKey, savedItem, absoluteExpiration); 
    } 

    public static T GetFromCache<T>(string cacheKey) where T : class 
    { 
     return MemoryCache.Default[cacheKey] as T; 
    } 

    public static void RemoveFromCache(string cacheKey) 
    { 
     MemoryCache.Default.Remove(cacheKey); 
    } 

    public static bool IsIncache(string cacheKey) 
    { 
     return MemoryCache.Default[cacheKey] != null; 
    } 
} 

La cosa bella di questo è che è thread-safe, e si prende cura della scadenza automaticamente la cache per voi. Quindi in pratica tutto quello che devi fare è controllare se ottenere un oggetto da MemoryCache è nullo o no. Nota comunque che MemoryCache è disponibile solo in .NET 4.0+

Se l'applicazione è un'applicazione web quindi utilizzare System.Web.Caching piuttosto che MemoryCache. System.Web.Caching è disponibile da .NET 1.1 e non ci sono ulteriori riferimenti che devi aggiungere al tuo progetto. Ecco la stessa classe di supporto per il web.

using System.Web; 

public static class CacheHelper 
{ 
    public static void SaveTocache(string cacheKey, object savedItem, DateTime absoluteExpiration) 
    { 
     if (IsIncache(cacheKey)) 
     { 
      HttpContext.Current.Cache.Remove(cacheKey); 
     } 

     HttpContext.Current.Cache.Add(cacheKey, savedItem, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 10, 0), System.Web.Caching.CacheItemPriority.Default, null); 
    } 

    public static T GetFromCache<T>(string cacheKey) where T : class 
    { 
     return HttpContext.Current.Cache[cacheKey] as T; 
    } 

    public static void RemoveFromCache(string cacheKey) 
    { 
     HttpContext.Current.Cache.Remove(cacheKey); 
    } 

    public static bool IsIncache(string cacheKey) 
    { 
     return HttpContext.Current.Cache[cacheKey] != null; 
    } 
} 

Ci sono altre politiche di cache di scadenza che è possibile utilizzare per entrambi i modelli, per la cache esempio sulla base di un percorso di file (s) in modo che quando un file cambia la cache automaticamente scade, la cache SQL dipendenza (fa polling periodico del server SQL per le modifiche), scadenza scorrevole o è possibile creare il proprio. Sono davvero a portata di mano.

Problemi correlati