这是对这个问题的跟进,其中包含相互矛盾的答案。我也对与更新版本的 ASP.NET 相关的答案感兴趣。
我的应用程序用于HttpRuntime.Cache
缓存一些永不过期的模型列表。它们在应用程序预热时加载,很少更改,但经常读取。
我的代码如下:
private void ReportRemovedCallback(string key, object value, CacheItemRemovedReason reason)
{
if (!ApplicationPoolService.IsShuttingDown())
{
var str = $"Removed cached item with key {key} and count {(value as IDictionary)?.Count}, reason {reason}";
LoggingService.Log(LogLevel.Info, str);
}
}
private IDictionary<int, T> ThreadSafeCacheAccessAction(Action<IDictionary<int, T>, bool> action = null)
{
// refresh cache if necessary
var dict = HttpRuntime.Cache[CacheDictKey] as IDictionary<int, T>;
bool invalidated = false;
if (dict == null)
{
lock (CacheLockObject)
{
// getting expiration times from model attribute
var cacheInfo = typeof(T).GetCustomAttributes(typeof(UseInCachedRepositoryAttribute), inherit: true).FirstOrDefault() as UseInCachedRepositoryAttribute;
int absoluteExpiration = cacheInfo?.AbsoluteExpiration ?? Constants.Cache.IndefiniteRetention;
int slidingExpiration = cacheInfo?.SlidingExpiration ?? Constants.Cache.NoSlidingExpiration;
dict = _modelRepository.AllNoTracking.ToList().Where(item => item.PkId != 0).ToDictionary(item => item.PkId, item => item);
HttpRuntime.Cache.Insert(CacheDictKey, dict, dependencies: null,
absoluteExpiration: DateTime.Now.AddMinutes(absoluteExpiration),
slidingExpiration: slidingExpiration <= 0 ? Cache.NoSlidingExpiration : TimeSpan.FromMinutes(slidingExpiration),
priority: CacheItemPriority.NotRemovable,
onRemoveCallback: ReportRemovedCallback);
invalidated = true;
}
}
根据此处提供的文档,我还在 web.config 中包含了以下标记:
<caching>
<cache disableExpiration="true" disableMemoryCollection="true" />
</caching>
但是,有时ReportRemovedCallback
会要求删除项目。我的感觉是来自 web.config 的缓存配置被忽略(文档清楚地表明它已经过时),这CacheItemPriority.NotRemovable
意味着只有“非常高的优先级”,而不是“从不删除”。
问题: 有没有办法说服 HttpRuntime.Cache 永远不要删除某些项目?还是我应该考虑另一种缓存机制?