【问题标题】:.NET 4 ObjectCache - Can We Hook Into a "Cache Expired" Event?.NET 4 ObjectCache - 我们可以挂钩“缓存过期”事件吗?
【发布时间】:2011-12-01 04:24:46
【问题描述】:

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

_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,但在我的示例中找不到任何有意义的文档/示例来说明如何使用它。

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

有什么想法吗?

【问题讨论】:

  • 顺便说一句,不需要设置Priority = CacheItemPriority.Default,因为这个默认值是默认设置的:)

标签: c# caching .net-4.0 objectcache


【解决方案1】:

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

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

【讨论】:

  • 嗯,该链接不包含代码示例——事实上,MSDN 对运行时缓存的代码示例非常少。我最终想通了,但你可以通过提供一个例子为我节省一个小时。
  • CodeProject sample "在 .NET 4.0 中使用 MemoryCache"
【解决方案2】:

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

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

特别是这条评论:

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

【讨论】:

  • 晚会,但我刚刚注意到您指的是System.Web.Caching 命名空间中的类型,而问题是关于System.Runtime.Caching 命名空间。
  • @StevenLiekens,他们将缓存移至 .NET 4 中的 System.RunTime,因为它非常有用
  • 您仍然可以在 .NET 4 及更高版本中使用 System.Web.Caching
【解决方案3】:

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

            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多