我有一个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();
}
}
答案 0 :(得分:1)
我认为这个问题的一个更好的解决方案是完全避免删除回调,并使用具有终结器的自定义类包装COM对象来执行ReleaseSession()调用。更好的方法是为COM对象实现某种对象池。
在您当前的实现中(使用已删除的回调),某人可能会将对象从缓存中取出,在完成缓存之前,缓存会决定修剪,从缓存中删除相同的对象。
从终结器线程进行COM调用会有一些危险(例如,如果STA线程没有泵送,STA对象可能会阻塞终结器),但不会比当前实现更糟糕。