是否有可能在C#中创建一个真正弱键的字典?

Man*_*nia 22 .net c# dictionary garbage-collection weak-references

我正试图坚持WeakKeyedDictionary<,>C#的真实细节......但我遇到了困难.

我意识到这是一个非常重要的任务,但似乎无法声明a WeakKeyedKeyValuePair<,>(如果密钥可达,GC只跟随值引用)使得它看起来似乎不可能.

我看到两个主要问题:

  1. 到目前为止,我所看到的每个实现都没有在收集密钥后修剪值.考虑一下 - 使用这样一个字典的主要原因之一是防止这些值被保留(不仅仅是键!),因为它们无法访问,但在这里它们被强引用指向.

    是的,在词典中添加/删除足够多,它们最终会被替换,但是如果你不这样做呢?

  2. 如果没有一个假设WeakKeyedKeyValuePair<,>(或告诉GC到的另一种方法只标出值,如果关键是可达)是指它的键永远不会被收集的任何值.存储任意值时,这是一个问题.

问题1可以在一个相当不理想/ hackish的方式来解决:使用GC通知等待一个完整的GC完成,然后沿着去修剪字典在另一个线程.这个我半熟的.

但问题2让我难过.我意识到这很容易被"所以不要这样做"所抵消,但我想知道 - 这个问题甚至可以解决吗?

dtb*_*dtb 29

看看ConditionalWeakTable <TKey,TValue> Class.

使编译器能够将对象字段动态附加到托管对象.

它本质上是一个字典,其中键和值都是WeakReference,只要键处于活动状态,该值就会保持活动状态.

注意!它使用的这个类不使用GetHashCodeEquals进行相等比较ReferenceEquals.

  • @Mania DependentHandle是[ephemerons](http://en.wikipedia.org/wiki/Ephemeron)的CLR实现,没有GC合作就无法实现.它应该像GCHandle一样公开.如果你不介意反思技巧,你可以将静态CLR方法转换为委托,并实现自己的DependentHandle和WeakValuedDictionary.小心研究.NET参考源(公共),或使用一些反编译器,因为它有棘手的竞争条件. (8认同)
  • 太可惜了,看来这取决于内部.NET的神奇"DependentHandle"为它的实现还..它忽略.GetHashCode和.Equals,充其量:(使其成为一个不合格的字典.此外得不到DependentHandle,问题现在已经搬到定义WeakValuedDictionary <,>,我想这可能是尽可能接近我们可以得到.. (3认同)
  • @Zarat:BTW,我希望看到一个框架类是一个`InternTable <T>`(带有`IEqualityComparer <T>`作为构造参数).给定一个`T`的实例,确定该表是否已经拥有一个比较相等的条目.如果是,请比较该实例; 否则,将提供的实例存储在表中并返回它.如果实现良好,这样的表可以极大地提高嵌套不可变类型的性能,其中哈希码可以非常可靠地区分不相等的实例,但是比较相等的实例是昂贵的. (2认同)