是否有任何带有超时的弱引用的实现



有时我需要在一段时间内在内存中保留对对象的引用。弱引用允许这样做,但时间受到垃圾收集周期的限制。该问题与此类似,但与 .NET 相关。

我知道有许多缓存内置了这样的功能,但我不需要利用完整缓存(即键值映射(来仅存储一个对象。它宁愿是一个单一的"可过期参考"。

我知道我可以自己实现它,但我正在寻找一个标准的实现(理想情况下集成在框架中,以防我错过它(

更新

根据@Jeroen Mostert和@dariogriffo的回答,我为这个问题添加了更多细节。

好的,所以有两种方法:要么使用键值缓存,要么使用基于计时器的回调。假设有一个对象树,每个对象都有一个对缓存值的引用。这些值具有过期超时。假设树节点的计数很大。如果我将每个值存储在 MemoryCahce 中,则需要为节点分配唯一键,并且通过哈希表搜索访问它们的值。此外,它还具有向表添加新键的计算复杂性。另一方面,如果我按照@dariogriffo的建议使用我的自定义WeakReferenceByTimeOut,那么它就没有这样的问题。相反,存在开销,因为我需要为每个值对象创建一个计时器对象(或我猜在内部使用计时器的 Task 对象(。从我的角度来看,第二种方法更好,但我不确定。

据我所知,也没有内置任何东西,所以这里有 1 分钟的实现

using System.Timers;
public class WeakReferenceByTimeOut<T> where T : class
{
    private Timer _timer;
    public WeakReferenceByTimeOut(T val, int miliseconds)
    {
        Reference = val;
        _timer = new Timer(miliseconds);
        _timer.Elapsed += KillReference;
        _timer.AutoReset = false;
        _timer.Enabled = true;
    }
    public T Reference { get; private set; }
    private void KillReference(object sender, ElapsedEventArgs e)
    {
        _timer.Elapsed -= KillReference;
        _timer.Dispose();
        _timer = null;
        Reference = null;   
    }        
}
如果条目

的有效期不应超过一定时间对您的要求很重要,那么,您确实需要某种缓存,即使它只是一个缓存。最简单的实现(如果您从未设置对其他任何内容的引用(是 Task.Delay(...).ContinueWith(t => myWeakReference = null) ,它不需要额外的类。如果您确实需要能够设置对其他内容的引用(这意味着重置计时器(,则需要一个包装类。

顺便说一下,我不建议编写一个支持将引用设置为其他内容的类 - 设置引用和在计时器到期时清除它之间存在固有的竞争条件。如果您需要这样的东西,几乎可以肯定,带有策略的经过审查的缓存实现会更好,即使您仅将其用于一个参考。

BCL中没有这样的事情;这是一个不寻常的情况。通常,您要么缓存多个值,要么不关心何时清理引用,只要缓存保持在一定的内存限制内。如果你有一个带有超时策略的缓存,如System.Runtime.Caching.MemoryCache,你可以在其中存储WeakReference实例,这应该实现同样的事情(但你需要仔细检查你从缓存中返回的条目是否仍然有效(。

相关内容

  • 没有找到相关文章

最新更新