简洁版本:
对于缓存类,我需要通知对象是否被垃圾回收(以从缓存中删除相应的条目)。最好的方法是什么?从析构函数发送事件?
长版:
我正在为使用一个巨大的参数树对象和许多小值类型参数的函数编写一个缓存器/内存器,例如
double myFunc(HugeParTree parTree, int dynPar1, double dynPar2)
我想通过以下方式缓存这些功能:
元组的缓存结果(parTree.GUID,dynPar1,dynPar2等)
每当
parTree
更改(很少发生)时,所有相应的缓存条目都将被删除(通过观察者模式)。 (parTree.Equals()
太昂贵了;它比较100多个值类型)。代码现在看起来像这样(对于一个value参数):
public class CachedFunction1ObsPar1Par<TRet, TObsPar1, TPar1>
where TObsPar1 : IObservable, IProvideGUID
{
public delegate TRet ValueCalculator(TObsPar1 obsPar1, TPar1 par1);
public CachedFunction1ObsPar1Par(ValueCalculator calc)
{
_calc = calc;
}
#region members
private ValueCalculator _calc;
private Dictionary<Guid, Dictionary<TPar1, TRet>> _cache =
new Dictionary<Guid, Dictionary<TPar1,TRet>>();
#endregion
public TRet value(TObsPar1 obsPar1, TPar1 par1)
{
TRet result;
bool cacheHit = checkCache(obsPar1, par1, out result);
if (cacheHit)
{
Debug.Assert(result.Equals(_calc(obsPar1, par1)));
return result;
}
else
{
result = _calc(obsPar1, par1);
_cache[obsPar1.GUID].Add(par1, result);
return result;
}
}
private bool checkCache(TObsPar1 obsPar1, TPar1 par1, out TRet result)
{
if (!_cache.ContainsKey(obsPar1.GUID))
{
_cache.Add(obsPar1.GUID, new Dictionary<TPar1, TRet>());
obsPar1._changed += this.invalidateCache;
}
Dictionary<TPar1, TRet> guidCache = _cache[obsPar1.GUID];
bool success = guidCache.TryGetValue(par1, out result);
return success;
}
private void invalidateCache(object sender)
{
TObsPar1 obsPar = (TObsPar1)sender;
_cache.Remove(obsPar.GUID);
obsPar._changed -= this.invalidateCache;
}
}
我还没有测试过,因为仍然存在以下问题:在不再使用相应的parTree之后,缓存条目永远不会被删除。我很喜欢一个同步解决方案,无需对非常旧的缓存条目进行重复的“扫描”。
最佳答案
对于缓存类,我需要通知对象是否为垃圾
收集(从我的缓存中删除相应的条目)。是什么
最好的方法吗?从析构函数发送事件?
如果您的缓存中包含普通(强)引用,则将永远不会收集这些项目。
如果您的缓存包含WeakReferences,则无需删除任何内容。