【发布时间】:2015-04-08 09:40:12
【问题描述】:
我正在研究如何正确创建弱引用事件处理程序。由于 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);
}
我问自己这个简单的解决方案是否已经有效,或者我是否忽略了一个重要方面,因为我在 Internet 上找到的大多数其他解决方案都很复杂且难以理解。到目前为止我能找到的最佳解决方案 使用未绑定的委托。这是某种将事件处理程序和事件订阅者实例作为参数的包装委托(是的,它需要在委托调用期间传入事件订阅者对象)。
你可以在这里找到这篇很棒的文章:
http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx#commentstart
“WeakEventManager”类不依赖于知道订阅者类或任何其他信息。除此之外,它还适用于匿名代表。如果一个解决方案只需要他们存储对委托的弱引用,为什么开发人员会花这么多时间来编写一个不仅可以工作而且使用方便的解决方案?有什么收获?
更新:因为有人对这个问题投了反对票(可能有点不具体),所以我想提出一个更准确的问题:
该源代码是否首先需要创建一个有效的弱事件处理程序?如果没有,缺少什么?
【问题讨论】:
-
您不需要反编译框架 .net 程序集,Microsoft provides the source code。这样你也可以在他们提供的代码中看到 cmets。
-
是的,你是对的。不幸的是,这次我无法使用“ProtectedAddHandler”方法。当我尝试时,我总是被重定向到页面顶部^^
-
它在line 253。
-
“它也适用于匿名代表”——这是一个毫无意义的陈述。一个委托是“匿名的”,因为它引用了一个匿名的方法;委托实例本身与任何其他委托完全一样,并且不需要额外的努力来支持此类委托。实际上,即使是匿名方法也只是声明它的匿名方法;编译器仍然给它一个名字。
-
不,这不是毫无意义的。由于基于未绑定委托的解决方案需要事件订阅者实例作为参数才能正常工作,因此您不能简单地声明匿名委托,因为它可能与实例无关。这是大多数非 WPF 解决方案的一大缺点。
标签: c# wpf weak-references