ObjectCache CachedObjectRemovedCallback 没有被调用?

Posted

技术标签:

【中文标题】ObjectCache CachedObjectRemovedCallback 没有被调用?【英文标题】:ObjectCache CachedObjectRemovedCallback not being called? 【发布时间】:2014-01-16 01:43:26 【问题描述】:

我有一个 WCF 服务,它正在实现一个自定义 ObjectCache 来缓存一个 3rd 方 COM 对象,以便与 3270 环境进行交互。

此第 3 方对象适用于许可模型,因此每次从缓存中删除对象时都必须调用我的 RemovedCallBack 以释放许可。

我的问题是,我一直在使用许可证,但 ObjectCache 中没有任何东西。这似乎项目正在从缓存中删除,但没有击中回调。这可能吗?如果我的缓存对象被 GC 清理掉了,它们还会触发回调吗?

这是我的实现:

private static readonly ObjectCache cache = MemoryCache.Default;

正在使用以下方式将项目添加到缓存中:

   public void AddToCache(String cacheKeyName, object cacheObject, int expiryMinutes)
        
            callback = CachedObjectRemovedCallback;

            // Sliding expiration
            policy = new CacheItemPolicy
            
                Priority = CacheItemPriority.Default,
                SlidingExpiration = TimeSpan.FromMinutes(expiryMinutes),
                RemovedCallback = callback
            ;

            // Add to cache
            cache.AddOrGetExisting(cacheKeyName, cacheObject, policy);
        

以及移除的回调:

private CacheEntryRemovedCallback callback;
private static void CachedObjectRemovedCallback(CacheEntryRemovedArguments arguments)
        
            // Always check if the object is a customtype, and if so, release the session/license
            if (arguments.CacheItem != null && IsCustomType(arguments.CacheItem.Value))
            
                // Release the custom session
                ICustomType customType= (ICustomType)arguments.CacheItem.Value;
                customType.ReleaseSession();
            
        

【问题讨论】:

您是否确认您的回调没有被调用,或者您只是在猜测? 我已经在回调中实现了日志记录,并且正在获取记录的条目,但我只是猜测其中一些没有被调用。 另外,您是否尝试过UpdateCallback,它应该在删除条目之前被调用? 我正在查看 UpdateCallback,但我不确定这对我有多大帮助,除非我遇到某种竞争条件。 是否有可能您的回调被调用但您的 if 语句以某种方式失败? 【参考方案1】:

我认为这个问题的更好解决方案是完全避免删除回调,并使用具有终结器的自定义类包装您的 COM 对象来执行 ReleaseSession() 调用。更好的是为您的 COM 对象实现某种对象池。

在您当前的实现中(使用删除的回调),有人可能将对象从缓存中取出,在他们完成之前,缓存决定修剪,从缓存中删除相同的对象。

从终结器线程执行 COM 调用存在一些危险(例如,如果 STA 线程没有泵送,STA 对象可能会阻塞终结器),但不会比您当前的实现更糟。

【讨论】:

以上是关于ObjectCache CachedObjectRemovedCallback 没有被调用?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 System.Runtime.Caching.ObjectCache 中的缓存策略?