18

我有一个像这样缓存的简单对象:

_myCache.Add(someKey, someObj, policy);

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

如果我有CacheItemPolicy这样的:

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

这意味着它将在1小时内到期。凉爽的。

但是将会发生的情况是,不幸的第一个用户在一小时后将不得不等待命中。

有什么办法可以挂钩“过期”事件/委托并手动刷新缓存?

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

PS。我知道我可以CacheItemPriority.NotRemovable手动使用和过期它,但在我当前的示例中我不能这样做,因为缓存的数据有点太复杂了(例如,我需要在我的代码中的 10 个不同位置“无效”)。

有任何想法吗?

4

3 回答 3

16

CacheItemPolicy被调用者有一个属性,RemovedCallback其类型为:CacheEntryRemovedCallback。不知道他们为什么不走标准的活动路线,但这应该可以满足您的需求。

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

于 2011-10-05T04:45:35.677 回答
5

这个聚会迟到了,但我刚刚注意到 CacheItemUpdate 和 CacheItemRemove 回调之间的一个有趣的区别。

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

特别是这条评论:

与 CacheItemRemovedReason 枚举不同,此枚举不包括 Removed 或 Underused 值。可更新缓存项不可删除,因此即使需要释放内存,ASP.NET 也永远不会自动删除。

于 2012-04-16T15:02:48.210 回答
2

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(() =>
                    {
                    });
                }

            }
于 2019-08-14T05:14:01.613 回答