首页 文章

在Web API中缓存数据

提问于
浏览
34

我需要缓存在ASP.NET Web API OData服务中可用的大部分是静态的(可能每天更改1次)的对象集合 . 此结果集用于跨调用(意味着不是特定于客户端调用),因此需要在应用程序级别缓存它 .

我做了一些关于'在Web API中缓存'的搜索,但所有结果都是关于'输出缓存' . 这不是我在这里寻找的 . 我想缓存一个'People'集合,以便在后续调用中重用(可能有一个滑动到期) .

我的问题是,由于这仍然只是ASP.NET,我是否使用传统的应用程序缓存技术将此集合持久存储在内存中,或者我还需要做些什么呢?此集合不直接返回给用户,而是通过API调用用作OData查询的幕后源 . 我没有理由在每次通话时都去数据库,以便在每次通话时获得完全相同的信息 . 每小时到期应该足够了 .

任何人都知道如何在这种情况下正确缓存数据?

2 回答

  • 38

    是的,输出缓存不是你想要的 . 您可以使用MemoryCache将数据缓存在内存中,例如http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx . 但是,如果应用程序池被回收,您将丢失该数据 . 另一种选择是使用AppFabric Cache或MemCache等分布式缓存来命名 .

  • 25

    我最终使用的解决方案涉及 System.Runtime.Caching 命名空间中的 MemoryCache . 以下是最终用于缓存我的集合的代码:

    //If the data exists in cache, pull it from there, otherwise make a call to database to get the data
    ObjectCache cache = MemoryCache.Default;
    
    var peopleData = cache.Get("PeopleData") as List<People>;
    if (peopleData != null)
       return peopleData ;
    
    peopleData = GetAllPeople();
    CacheItemPolicy policy = new CacheItemPolicy {AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30)};
    cache.Add("PeopleData", peopleData, policy);
    return peopleData;
    

    这是我发现使用 Lazy<T> 考虑锁定和并发的另一种方法 . 信用总额发到这篇文章:How to deal with costly building operations using MemoryCache?

    private IEnumerable<TEntity> GetFromCache<TEntity>(string key, Func<IEnumerable<TEntity>> valueFactory) where TEntity : class 
    {
        ObjectCache cache = MemoryCache.Default;
        var newValue = new Lazy<IEnumerable<TEntity>>(valueFactory);            
        CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30) };
        //The line below returns existing item or adds the new value if it doesn't exist
        var value = cache.AddOrGetExisting(key, newValue, policy) as Lazy<IEnumerable<TEntity>>;
        return (value ?? newValue).Value; // Lazy<T> handles the locking itself
    }
    

相关问题