【发布时间】:2017-09-01 08:08:15
【问题描述】:
这是this question 的后续内容,其中包含相互矛盾的答案。我也对与更新版本的 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;
}
}
根据here 提供的文档,我还在 web.config 中包含了以下标记:
<caching>
<cache disableExpiration="true" disableMemoryCollection="true" />
</caching>
但是,有时会调用ReportRemovedCallback 来移除项目。我的感觉是 web.config 中的缓存配置被忽略了(文档明确指出它已过时),CacheItemPriority.NotRemovable 仅表示“非常高的优先级”,而不是“永不删除”。
问题: 有没有办法说服 HttpRuntime.Cache 永远不要删除某些项目?或者我应该考虑另一种缓存机制吗?
【问题讨论】:
-
我总是使用好的和旧的静态变量,它在 AppDomain 的生命周期内保留(例如,直到池回收)。如果由于某种原因您不能使用静态变量,请在您链接的问题中查找@user134706 答案,也许您可以了解您的案例发生了什么。
-
@Alisson - 我认为没有理由不使用静态变量。我已经将所有涉及
HttpRuntime.Cache的操作嵌入到一个关键部分中,因此替换应该很容易执行。感谢您的提示。
标签: asp.net asp.net-mvc caching httpruntime.cache cache-expiration