我有一个像这样缓存的简单对象:
_myCache.Add(someKey, someObj, policy);
_myCache
被声明为ObjectCache
(但通过DI注入为MemoryCache.Default
),someObj
是我要添加的对象,而policy
是CacheItemPolicy
。
如果我有CacheItemPolicy
这样的话:
var policy = new CacheItemPolicy
{
Priority = CacheItemPriority.Default,
SlidingExpiration = TimeSpan.FromHours(1)
};
这意味着它将在1小时后到期。凉。
但会发生的事情是,一小时后不幸的第一个用户将不得不等待命中。
有什么方法可以挂钩到“过期”的事件/委托并手动刷新缓存?
我看到提到CacheEntryChangeMonitor
,但在我的示例中找不到任何有意义的doco /示例如何使用它。
PS。我知道我可以使用CacheItemPriority.NotRemovable
并手动过期,但我不能在我当前的例子中这样做,因为缓存的数据有点太复杂(例如我需要在10个不同的地方“无效”我的代码)。
有什么想法吗?
答案 0 :(得分:14)
CacheItemPolicy
上有一个名为RemovedCallback
的属性,其类型为:CacheEntryRemovedCallback
。不确定为什么他们没有采用标准的活动路线,但这应该做你需要的。
http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.removedcallback.aspx
答案 1 :(得分:5)
参加派对的人来晚了,但我刚刚注意到CacheItemUpdate和CacheItemRemove回调之间存在一些有趣的区别。
http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemupdatereason.aspx
特别是这条评论:
与CacheItemRemovedReason枚举不同,此枚举可以 不包括已删除或未使用的值。可更新的缓存项目 是不可移动的,因此永远不会被自动删除 ASP.NET即使有需要释放内存。
答案 2 :(得分:1)
这是我在缓存过期时使用CacheRemovedCallback
事件的方式。
我分享关注的人。
public static void SetObjectToCache<T>(string cacheItemName, T obj, long expireTime)
{
ObjectCache cache = MemoryCache.Default;
var cachedObject = (T)cache[cacheItemName];
if (cachedObject != null)
{
// remove it
cache.Remove(cacheItemName);
}
CacheItemPolicy policy = new CacheItemPolicy()
{
AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds(expireTime),
RemovedCallback = new CacheEntryRemovedCallback(CacheRemovedCallback)
};
cachedObject = obj;
cache.Set(cacheItemName, cachedObject, policy);
}
public static void CacheRemovedCallback(CacheEntryRemovedArguments arguments)
{
var configServerIpAddress = Thread.CurrentPrincipal.ConfigurationServerIpAddress();
long configId = Thread.CurrentPrincipal.ConfigurationId();
int userId = Thread.CurrentPrincipal.UserId();
var tagInfoService = new TagInfoService();
string returnCode = string.Empty;
if (arguments.CacheItem.Key.Contains("DatatableTags_"))
{
// do what's needed
Task.Run(() =>
{
});
}
}