2013-08-12 155 views
10

在新的泛型在C#中,我试图创建一个存储,我的程序的其他部分可以要求模型对象。 这个想法是,如果我的缓存类有对象,它会检查它的日期,并返回它,如果对象不老,那么10分钟。 如果大于10分钟,则从服务器在线下载更新后的模型。 它没有对象下载并返回它。如何创建缓存对象的类?

但我遇到一些问题,我的对象与DateTime配对,使它们都是通用的。

// 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

你可以提供有关配对对象的问题/错误的更多细节吗?可能你可以尝试类而不是结构'DatedObject',如果你不想创建自己的类对象,尝试Tuple – Rex

+0

[Akavache](https://github.com/github/Akavache)可能值得寻找成。 –

回答

22

退房可作为.NET框架http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

你需要的System.RunTime.Caching组件添加作为您的应用程序引用的一部分内存缓存类。以下是添加项目并将其从缓存中删除的助手类。

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

这件事的好处是它是线程安全的,并且它会自动为您过期缓存。所以基本上你所要做的就是检查从MemoryCache获取一个项目是否为null。 Note但是,MemoryCache仅在.NET 4.0+中可用

如果您的应用程序是Web应用程序,则使用System.Web.Caching而不是MemoryCache。 System.Web.Caching自.NET 1.1以来一直可用,并且没有其他引用必须添加到您的项目中。 Heres是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; 
    } 
} 

有基于文件的路径(S)上的其他缓存过期策略,你可以使用这两种模式,例如缓存,这样,当一个文件自动改变缓存过期,SQL缓存依赖(不定期轮询SQL服务器以进行更改),滑动过期或您可以自行构建。他们来得非常方便。