1

我有一个对象(委托)需要保持活动状态(不是垃圾收集),而另一个对象(目标对象)是活动的。我希望在收集 TargetObject 时对 Delegate 进行垃圾收集(或至少可用于收集)。

困难在于我不想从 TargetObject 引用 Delegate,因为我希望它适用于不知道 Delegate 的现有对象,并且我不想影响 TargetObject 的生命周期。这是可能吗?

谢谢。

编辑:感谢到目前为止的回复。我会尽量澄清我在做什么。

我正在尝试实现弱事件,但我不是 WeakEventManager(尤其是 IWeakEventListener)的粉丝。我想持有对指向对象 TargetObject 中的方法的委托事件处理程序 (Delegate) 的弱引用。在 TargetObject 存活时需要对 Delegate 进行强引用以保持 Delegate 存活,但如果生命周期较长的东西引用 Delegate,它会使 TargetObject 保持存活(违背了弱事件的目的)。

如果订阅弱事件的对象不必具有任何特殊的实现细节(例如必须保留委托集合),那就太好了。

编辑编辑:将“A”更改为“Delegate”,将“B”更改为“TargetObject”

4

5 回答 5

3

神圣的死灵,但ConditionalWeakTable只是做你需要的。它允许将值与任意键关联,将键值对作为ephemerons(正是您正在寻找的,2 年前的现在......不幸的是,当时没有 .NET 4)。

即使没有ConditionalWeakTable解决方案,也可能是 a Dictionary<WeakReference, Delegate>,定期扫描以删除旧的死值(即,每当字典大小翻倍时,删除所有死对)。使用此解决方案,如果 Delegate 引用 TargetObject 它会阻止收集该对 - 一个问题ConditionalWeakTable旨在解决。

只是发布这个以防万一有人发现它有用。

于 2011-12-13T12:37:11.733 回答
2

这对我来说听起来像是一个设计问题。如果 B 不需要知道 A 的实例,那你为什么关心 A 是否活着?

您可以使用对 B 的弱引用和对 A 的强引用的容器对象以及定期检查弱引用是否仍然存在的计时器来执行此操作......但这将是一个非常糟糕的 hack。

如果你能解释为什么你认为你需要这个,我们可能会提出一个更好的方法。

于 2009-09-17T07:29:45.570 回答
1

为什么不直接从 B 引用 A?
这将使 A 保持活力,并且不需要 A 意识到 B...

于 2009-09-17T07:44:52.343 回答
0

我认为拥有一个没有任何引用的“活动”对象不是一个好的设计。

您始终可以创建一个静态列表,其中包含对应该保持活动状态的对象的引用,但当然您必须自己管理它。

我没有看到一个干净的解决方案,但也许 StackOverflow 上的一些超级生物会想出一个解决方案。

于 2009-09-17T07:29:17.110 回答
0

在 B 的析构函数(finalize)方法中抛出一个事件,并为那个杀死 A 的事件编写一个处理程序。

于 2009-09-17T07:42:49.647 回答