没有调用ObjectCache CachedObjectRemovedCallback?

时间:2013-12-28 18:46:36

标签: c# wcf caching memorycache objectcache

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

此第三方对象适用于许可模型,因此每次从缓存中删除对象以释放许可时,都必须调用我的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();
            }
        }

1 个答案:

答案 0 :(得分:1)

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

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

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