[英]How to create a Weak Referenced Event Handler?
我正在研究如何正确创建弱引用事件处理程序。 由于WPF已经有一个避免事件内存泄漏的解决方案,我反编译了“WeakEventManager”类并花了一些时间来分析它。
正如我所发现的,“WeakEventManager”类依赖于创建和存储对目标对象以及事件处理程序委托的弱引用。 以下是一些代码段:
this._list.Add(new WeakEventManager.Listener(target, handler));
public Listener(object target, Delegate handler)
{
this._target = new WeakReference(target);
this._handler = new WeakReference((object) handler);
}
我问自己,这个简单的解决方案是否已经有效,或者我忽略了一个重要方面,因为我在互联网上找到的大多数其他解决方案都很复杂且难以理解。 到目前为止,我能找到的最佳解决方案是使用未绑定的委托。 这是某种包装器委托,它将事件处理程序和事件订阅者实例作为参数(是的,它要求在委托调用期间传递事件订阅者对象)。
你可以在这里找到这篇精彩的文章:
http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx#commentstart
“WeakEventManager”类不依赖于了解订阅者类或任何其他信息。 除此之外,它还可以与匿名代表合作。 为什么开发人员花了这么多时间编写一个不仅工作而且使用方便的解决方案,如果解决方案只要求他们存储对委托的弱引用? 有什么收获?
更新 :因为有人贬低了这个问题(可能有点不明确),我想提出一个更精确的问题:
这个源代码首先是创建一个有效的弱事件处理程序吗? 如果没有,缺少什么?
我忽略了一个重要方面
是的,一个重要的。 你换了另一个“泄漏”。 您现在可以防止收集WeakReference对象,而不是阻止事件订阅者对象收集垃圾。 你没有领先。
还需要一种机制来清除那些陈旧的WeakReferences。 当IsAlive属性返回false时,您不再需要它们,然后将其从_list
删除。 但你必须单独检查, 有些代码需要处理。 一个明显的选择是检查何时添加事件或何时触发事件。 但这还不够,因为客户端代码只会在初始化时添加,并且无法保证事件始终被触发。
所以, 某种方案的需要以后做。 任何事都是可能的,没有什么是非常理想的,因为经常没有完成任何工作需要很多繁忙的工作。 做出正确的选择很重要。 而这当然也包括不这样做的话,那往往是一个创可贴在设计问题。
WeakEventManager
背后的想法是它保留一个对事件的目标对象的弱引用列表和它必须调用的处理程序列表,但不“将它们绑在一起”(直接订阅事件通常会这样做),允许目标是垃圾收集(并定期检查,以便在源被垃圾收集时相应地清空“订阅的”委托列表)。
这听起来很简单,需要大量的管道代码,这就是WeakEventManager
所做的一切(以易于使用的方式为您做管道工作)。
如果你将WeakEventManager
克隆到你自己的实现(或者使用内置的)并且它就是这样做,那么是的,这就是你需要做的全部。 如果这不是你问的问题,那么这个问题我不清楚。
这个源代码首先是创建一个有效的弱事件处理程序吗? 如果没有,缺少什么?
这是最重要的一点, Listener
类的其余部分也很重要,更不用说支持这个非委托事件处理程序所需的手动管道。
例如,检查一下ListenerList.DeliverEvent
,它比通常的Invoke
调用更复杂一些。
基本上,正常事件系统假设强引用,因此为了使用WeakReference
您最终必须自己添加大量翻译逻辑,以及决定如何处理因使用WeakReference
而从未触发的事件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.