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 没有被调用?的主要内容,如果未能解决你的问题,请参考以下文章