如何创建一个缓存对象的类?

11

我刚开始学习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;
    }
}

1
你能否提供有关配对对象时出现的问题/错误的更多细节?也许你可以尝试使用类而不是结构体来定义“DatedObject”,如果你不想创建自己的类对象,可以尝试使用元组。 - Rex
可能值得考虑Akavache - Sameer Singh
1个回答

26
请查看作为.NET框架一部分可用的内存缓存类,需要将System.RunTime.Caching程序集添加到应用程序引用中。以下是一个帮助类,可用于向缓存中添加和删除项目。http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx
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中获取的项是否为空即可。但是请注意,MemoryCache仅适用于.NET 4.0+。
如果您的应用程序是Web应用程序,则使用System.Web.Caching而不是MemoryCache。System.Web.Caching自.NET 1.1以来就可用,您无需向项目添加其他引用。以下是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;
    }
}

还有其他的缓存过期策略可以用于这两种模式,例如基于文件路径的缓存,当文件更改时,缓存会自动过期;SQL 缓存依赖(定期轮询 SQL 服务器以获取更改);滑动过期或者你可以自己构建。它们非常有用。


一个问题。为什么要使用静态类?任何人都可以回答。 - Ihtsham Minhas
1
@IhtshamMinhas 我认为主要问题是我们只想要一个对象供其他对象引用缓存。单例可能是另一种选择,但我不够聪明来说在这种情况下什么更好。 - The Fluffy Robot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接