使对象的生命周期依赖于另一个,而后者不会引用前者

时间:2013-12-04 14:21:18

标签: .net c#-4.0 memory garbage-collection

我正在开发一个类库。

经常调用一种实用程序方法,并传递复杂的第三方对象。 该方法使用来自模型的数据来收集时间。 因此,出于性能原因,我想将数据缓存到Dictionary类中,以便收集必要的数据一次,然后使其可用于所有连续调用。

然而,由于多种原因,要求图书馆的消费者维护一个可以存储字典的对象实例是不方便的。

是否可以创建一个可以像静态字段一样访问的对象,但是如果收集了另一个(指定的)对象则会收集该对象?

准码:

SomeMethodRequiringALotOfDataFromHugeSystem(detector detectorInHugeSystem)
{
   //access HugeSystem from a property in the dectector.
   //find if Huge System already has a Dictioary.
   //Build a Dictionary from data in Huge system if necessary.

   //(Not possible?) Associate the dictionary to the HugeSystem object instance so that Dictionary will be collected if HugeSystem instance is collected.

   // Perform time efficient task based on Dictionary.
}

2 个答案:

答案 0 :(得分:1)

我认为你可以使用ConditionalWeakTable来解决这个问题。 它主要是为语言编译器设计的,但没有什么能阻止你将它用于其他目的。

  

ConditionalWeakTable会在表格外没有其他对键的引用时自动删除键/值条目

因此,如果要创建在收集对象B时将收集的对象A,则应将{key = B,value = A}添加到ConditionalWeakTable。 您可以随时yourTable.TryGetValue(B)访问A.确保在其他任何地方都没有任何其他永久性的​​A引用,那么在收集B时应该收集A.

(请记住,垃圾收集器不会在不再引用后立即收集对象。特别是大型对象可能会自动在第2代中结束,只会偶尔收集它们。

另请参阅此stackoverflow answer有关ConditionalWeakTable的使用情况

答案 1 :(得分:0)

WeakReference专门针对此类情况而制作。

  

弱引用允许垃圾收集器在仍允许应用程序访问对象的同时收集对象。如果您需要该对象,您仍然可以获得它的强引用并防止它被收集。