我可以使 C# 对象的生命周期依赖于另一个对象吗?
我有一个对象(Delegate)需要在另一个对象(TargetObject)处于活动状态时保持活动状态(不是垃圾收集)。我希望在收集 TargetObject 时对 Delegate 进行垃圾收集(或至少可用于收集)。
困难在于我不想从 TargetObject 引用 Delegate,因为我希望它适用于不知道 Delegate 的现有对象,并且我不想影响 TargetObject 的生命周期。这有可能吗?
谢谢。
编辑:感谢迄今为止的回复。我会尽力澄清我在做什么。
我正在尝试实现弱事件,但我不喜欢 WeakEventManager(特别是 IWeakEventListener)。我想持有对委托事件处理程序(Delegate)的弱引用,该处理程序指向对象 TargetObject 中的方法。当 TargetObject 处于活动状态时,需要对 Delegate 进行强引用以保持 Delegate 处于活动状态,但如果生命周期较长的对象引用 Delegate,则它会保持 TargetObject 处于活动状态(违背了弱事件的目的)。
如果订阅弱事件的对象不必具有任何特殊的实现细节(例如必须保留委托集合),那就太好了。
编辑编辑:将“A”更改为“委托”,将“B”更改为“TargetObject”
I have an object (Delegate) which needs to stay alive (not garbage collected) while another object (TargetObject) is alive. I want Delegate to be garbage collected when TargetObject is collected (or at least available for collection).
The difficulty is that I don't want to need to reference Delegate from TargetObject since I want it to work for existing objects unaware of Delegate, and I don't want to affect the lifetime of TargetObject. Is this at all possible?
Thanks.
Edit: Thanks for the responses so far. I'll try to clarify what I'm up to.
I'm trying to implement weak events but I'm not a fan of the WeakEventManager (particularly IWeakEventListener). I want to hold a weak reference to a delegate event handler (Delegate) which points to a method in object TargetObject. There needs to be a strong reference to Delegate while TargetObject is alive to keep Delegate alive, but if something with a longer lifetime references Delegate, it keeps TargetObject alive (defeating the purpose of the weak event).
It would be nice if objects subscribing to weak events didn't have to have any special implementation details such as having to hold on to a collection of delegates.
Edit Edit: Changed 'A' to 'Delegate' and 'B' to 'TargetObject'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
神圣的死灵,但
ConditionalWeakTable
正是这样做的你需要的。它允许将值与任意键关联,键值对为ephemerons(正是您我们正在寻找,两年前的现在..不幸的是.NET 4当时还不可用)。即使没有
ConditionalWeakTable
,解决方案也可能是Dictionary
,定期清除以删除旧的死值(即,每当字典大小加倍时,删除所有死值)对)。使用此解决方案,如果委托引用 TargetObject,它会阻止该对的收集 -ConditionalWeakTable
旨在解决这个问题。只是发布此内容以防有人发现它有用。
Holy necro, but
ConditionalWeakTable
does just what you needed. It allows associating values with arbitrary keys, with the key value pairs as ephemerons (exactly what you were looking for, 2 years ago now.. unfortunately .NET 4 wasn't available then).Even without
ConditionalWeakTable
a solution could have been aDictionary<WeakReference, Delegate>
, with periodic sweeping to remove old dead values (ie whenever the Dictionary doubles in size, remove all dead pairs). With this solution if a Delegate refers to TargetObject it'd prevent collection of the pair though - a problemConditionalWeakTable
was designed to resolve.Just posting this in case anyone might find it useful.
对我来说这听起来像是一个设计问题。如果B不需要知道A的实例,为什么还要关心A是否还活着呢?
您可以可能使用一个具有对 B 的弱引用和对 A 的强引用的容器对象,以及一个定期检查弱引用是否仍然存在的计时器来做到这一点......但这将是一个很好的选择糟糕的黑客。
如果您能解释为什么您认为您需要这个,我们也许可以建议更好的方法。
This sounds like a design issue to me. If B doesn't need to know about the instance of A, why do you care about whether A is alive or not?
You can possibly do this using a container object with a weak reference to B and a strong reference to A, and a timer periodically checking whether the weak reference is still alive... but it would be a pretty grotty hack.
If you can explain why you think you need this, we may be able to suggest a better approach.
为什么不直接从 B 中引用 A?
这将使A保持活力并且不需要A知道B......
Why don't you just reference A from B?
That will keep A alive and does not require A to be aware of B...
我认为拥有一个没有任何引用的“活动”对象并不是一个好的设计。
您始终可以创建一个静态列表,其中包含对应该保持活动状态的对象的引用,但当然您必须自己管理它。
我没有看到一个干净的解决方案,但也许 StackOverflow 上的一些超级人物会想出一个解决方案。
I don't think it's good design to have an "alive" object that doesn't have any references to it.
You could always create a static List with references to objects that should stay alive, but of course you'd have to manage that yourself.
I don't see a clean solution for that, but maybe some of the super-beings on StackOverflow will come up with a solution.
在 B 的析构函数(finalize)方法中抛出一个事件,并为该事件编写一个处理程序来杀死 A。
Throw an event in the destructor (finalize) method of B, and write a handler for that event that kills A.