我想永远缓存某些值,并且希望确定,当我访问它们时,它们就在那里。
目前,我使用以下代码:
ObjectCache objectCache = MemoryCache.Default;
CacheItemPolicy policy = new CacheItemPolicy() { AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration };
objectCache.Set(new CacheItem("anykey", anyobject), policy);在有关MSDN的文档中,将编写关于设置ObjectCache.InfiniteAbsoluteExpiration的以下内容:
但是,具有此设置的缓存项可以出于由特定缓存实现确定的其他原因而从缓存中逐出,例如由内存压力引起的更改监视器事件驱逐。
这是否意味着,如果我的windows服务会与OutOfMemoryException崩溃,任何缓存值都将被清除?
发布于 2016-11-14 21:55:17
简单的回答是:是的,即使使用InfiniteAbsoluteExpiration,缓存值也可以被逐出或清除。
如果您的程序无法处理丢失的缓存值(它可能应该这样做),那么您需要处理一个项被删除以便驱逐的情况,而不管OutOfMemoryExceptions如何。MemoryCache (作为ObjectCache的一部分)有一个UpdateCallback委托,可以这样设置:
private void PopulateCache(Widget value)
{
var policy = new CacheItemPolicy();
policy.UpdateCallback = CacheUpdate;
_cache.Set(GetCacheItemKey(value), value, policy);
}
private void CacheUpdate(CacheEntryUpdateArguments args)
{
// if expired or evicted, put it back in!
if (args.RemovedReason == CacheEntryRemovedReason.Expired || args.RemovedReason == CacheEntryRemovedReason.Evicted)
{
_cache.Set(args.Key, _cache[args.Key], CacheItemPolicy);
}
// if removed or ChangeMonitorChanged, do nothing
}有关更多信息,请查看:https://msdn.microsoft.com/en-us/library/dd988702(v=vs.110).aspx
但是,作为一种最佳实践,典型的模式是,当您从缓存中检索一个值时,如果该项已过期/被逐出,您应该从数据存储中获取该项并重新填充缓存。
发布于 2017-09-12 15:22:17
虽然Finster的答案是正确的,但如果您使用的是MemoryCache (MemoryCache.Default)的默认实例,我将对其进行添加。
不知何故,简单的Set方法不会向UpdateCallback中的默认实例添加新的CacheItem (或者至少在以后的缓存读取中是不可用的)。
基本上,您需要直接在CacheItem函数参数对象上设置新的UpdatedCacheItem,这解决了这个问题。
private void CacheUpdate(CacheEntryUpdateArguments args)
{
// if expired or evicted, put it back in!
if (args.RemovedReason == CacheEntryRemovedReason.Expired || args.RemovedReason == CacheEntryRemovedReason.Evicted)
{
args.UpdatedCacheItem = new CacheItem(args.Key, "value");
args.UpdatedCacheItemPolicy = new CacheItemPolicy();
}
}学分:http://pdalinis.blogspot.com/2013/06/auto-refresh-caching-for-net-using.html
https://stackoverflow.com/questions/31453492
复制相似问题