1

我有一个 WCF 服务,它正在实现一个自定义 ObjectCache 来缓存第 3 方 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();
            }
        }
4

1 回答 1

1

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

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

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

于 2013-12-28T20:49:08.347 回答