当前位置:  开发笔记 > 后端 > 正文

在Web API中缓存数据

如何解决《在WebAPI中缓存数据》经验,为你挑选了2个好方法。

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

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

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

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



1> atconway..:

该解决方案我最终使用参与MemoryCacheSystem.Runtime.Caching命名空间.以下是最终用于缓存我的集合的代码:

//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;
if (peopleData != null)
   return peopleData ;

peopleData = GetAllPeople();
CacheItemPolicy policy = new CacheItemPolicy {AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30)};
cache.Add("PeopleData", peopleData, policy);
return peopleData;

这是我发现使用的另一种方法Lazy来考虑锁定和并发.这篇文章的总功劳:如何使用MemoryCache处理昂贵的建筑操作?

private IEnumerable GetFromCache(string key, Func> valueFactory) where TEntity : class 
{
    ObjectCache cache = MemoryCache.Default;
    var newValue = new Lazy>(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>;
    return (value ?? newValue).Value; // Lazy handles the locking itself
}



2> Pablo Cibrar..:

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


作为帮助人们的标记,Azure中推荐的缓存技术现在是Redis.如果您有多个API实例,则需要Redis或其他分布式缓存.Azure托管缓存现在非常隐藏,只能从Powershell访问.他们只是把它留在那里帮助以前使用它的人.
是的,写完这些后,我在看起来很完美的System.Runtime.Caching`命名空间中找到了“ MemoryCache”。如果AppPool回收,我可以放松数据的警告是可以的,因为我只是想防止在* API *调用中重新调用DB。使用`MemoryCache.Get()和`MemoryCache.Add()`对我来说似乎很好。`AddOrGetExisting()`看起来很酷,但不适用于我的情况。它仍然需要在调用之前先从数据库获取数据。我将“ AbsoluteExpiration”设置为30分钟。
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有