.NET 4 ObjectCache -我们可以钩入一个“缓存过期”吗?事件

本文关键字:缓存 一个 过期 缓存过期 事件 我们 ObjectCache NET | 更新日期: 2023-09-27 18:10:23

我有一个简单的对象缓存如下:

_myCache.Add(someKey, someObj, policy);

其中_myCache被声明为ObjectCache(但通过DI注入为MemoryCache.Default), someObj是我要添加的对象,policyCacheItemPolicy

如果我有一个这样的CacheItemPolicy:

var policy = new CacheItemPolicy 
{ 
   Priority = CacheItemPriority.Default, 
   SlidingExpiration = TimeSpan.FromHours(1)
};

表示1小时后过期。酷。

但是会发生的是,第一个在一小时后的倒霉的用户将不得不等待点击。

是否有办法我可以挂钩到一个"过期"的事件/委托和手动刷新缓存?

我看到有提到CacheEntryChangeMonitor,但找不到任何有意义的文档/例子如何在我的例子中使用它。

p。我知道我可以使用CacheItemPriority.NotRemovable并手动过期,但我不能在我当前的例子中这样做,因为缓存的数据有点太复杂(例如,我需要在我的代码中像10个不同的地方"无效")。

任何想法?

.NET 4 ObjectCache -我们可以钩入一个“缓存过期”吗?事件

CacheItemPolicy上有一个名为RemovedCallback的属性,其类型为:CacheEntryRemovedCallback。不知道为什么他们不走标准的事件路线,但这应该是你需要的。

http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.removedcallback.aspx

来得太晚了,但我刚刚注意到CacheItemUpdate和CacheItemRemove回调之间有一个有趣的区别。

http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemupdatereason.aspx

特别是这个注释:

不像CacheItemRemovedReason枚举,这个枚举做不包括已移除或未充分使用的值。可更新的缓存项是不可移动的,因此永远不能被自动移动ASP。. NET,即使需要释放内存。

这是我在缓存过期时使用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(() =>
                    {
                    });
                }
            }