C# 即使使用了InfinitiableSoluteExption,也可以从ObjectCache中逐出值吗?

C# 即使使用了InfinitiableSoluteExption,也可以从ObjectCache中逐出值吗?,c#,caching,C#,Caching,我希望永远缓存某些值,并希望确保当我访问它们时它们都在那里 目前我使用以下代码: ObjectCache objectCache = MemoryCache.Default; CacheItemPolicy policy = new CacheItemPolicy() { AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration }; objectCache.Set(new CacheItem("anykey", anyobject

我希望永远缓存某些值,并希望确保当我访问它们时它们都在那里

目前我使用以下代码:

ObjectCache objectCache = MemoryCache.Default;
CacheItemPolicy policy = new CacheItemPolicy() { AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration };

objectCache.Set(new CacheItem("anykey", anyobject), policy);
在MSDN上的文档中,关于设置ObjectCache.InfinitiableSoluteExpiration的内容如下:

但是,可以从缓存中逐出具有此设置的缓存项 由特定缓存确定的其他原因 实现,例如由 内存压力

资料来源:


这是否意味着,如果我的windows服务因OutOfMemoryException而崩溃,那么任何缓存值都将被清除?

简短的回答是:是的,即使使用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
}
有关更多信息,请查看:


然而,作为最佳实践,典型的模式是,当您从缓存中检索值时,如果该项过期/被逐出,您应该从数据存储中获取该项并重新填充缓存。

虽然Finster的答案是正确的,但如果您使用的是MemoryCache的默认实例(MemoryCache.default),我将对其进行添加

不知何故,simple
Set
方法不会在UpdateCallback中将新的CacheItem添加到默认实例中(或者至少在后续的缓存读取中不可用)

基本上,您需要直接在UpdatedCacheItem函数参数对象上设置新的CacheItem,这就解决了问题

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();
    }
}
学分: