如何创建一个弱引用事件处理程序?

Den*_*sel 4 c# wpf weak-references

我正在研究如何正确创建弱引用事件处理程序.由于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);
  }
Run Code Online (Sandbox Code Playgroud)

我问自己,这个简单的解决方案是否已经有效,或者我忽略了一个重要方面,因为我在互联网上找到的大多数其他解决方案都很复杂且难以理解.到目前为止,我能找到的最佳解决方案是使用未绑定的委托.这是某种包装器委托,它将事件处理程序和事件订阅者实例作为参数(是的,它要求在委托调用期间传递事件订阅者对象).

你可以在这里找到这篇精彩的文章:

http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx#commentstart

"WeakEventManager"类不依赖于知道订阅者类或任何其他信息.除此之外,它还可以与匿名代表合作.为什么开发人员花了这么多时间编写一个不仅工作而且使用方便的解决方案,如果解决方案只要求他们存储对委托的弱引用?有什么收获?

更新:因为有人贬低了这个问题(可能有点不明确),我想提出一个更精确的问题:

这个源代码首先是创建一个有效的弱事件处理程序吗?如果没有,缺少什么?

Han*_*ant 7

我忽略了一个重要方面

是的,一个重要的.你换了另一个"泄漏".您现在可以防止收集WeakReference对象,而不是阻止事件订阅者对象收集垃圾.你没有领先.

什么是需要的是一种机制,让那些陈旧在WeakReferences清理的.当IsAlive属性返回false时,您不再需要它们,然后将其从中删除_list.但你必须单独检查,有些代码需要处理.一个明显的选择是检查何时添加事件或何时触发事件.但这还不够,因为客户端代码只会在初始化时添加,并且无法保证事件始终被触发.

所以一些一种方案是需要以后做.任何事都是可能的,没有什么是非常理想的,因为经常没有完成任何工作需要很多繁忙的工作.做出正确的选择很重要.而这当然也包括这样做的话,那往往是一个创可贴在设计问题.


Guv*_*nte 0

该源代码是否最重要的是创建一个有效的弱事件处理程序?如果没有,还缺少什么?

这是最重要的一点,Listener类的其余部分也很重要,更不用说支持此非委托事件处理程序所需的手动管道了。

例如,检查ListenerList.DeliverEvent哪个比通常的调用更复杂一些Invoke

基本上,正常的事件系统假设强引用,因此为了使用,WeakReference您最终必须自己添加大量翻译逻辑,并决定如何处理由于使用而永远不会触发的事件WeakReference