我正在参考有关弱事件的 MSDN 教程。我了解了基础知识。我正在从事一个非 WPF 项目,我的班级正在公开某些事件。我的问题是,弱事件是否完全取代了旧的事件模式?每个暴露事件的类都使用它好吗?随意使用弱事件有什么副作用?
4 回答
根据我所做的阅读,使用 WeakEvents 似乎没有任何特定的负面影响,除了这样做更冗长。此外,在大多数情况下,您应该能够在不再需要事件时手动取消注册。在某些情况下,这是不可能的。例如,您引用的 MSDN 页面提到何时应该使用 WeakEvents:
http://msdn.microsoft.com/en-us/library/aa970850.aspx
某些场景本身就适合弱事件模式的应用。一种这样的场景是数据绑定。在数据绑定中,源对象通常完全独立于作为绑定目标的侦听器对象。WPF 数据绑定的许多方面已经在如何实现事件中应用了弱事件模式。
唯一向他们提出任何负面意见的人是这个博客:
一般来说,使用弱事件侦听器有一些缺点:
- 它的符号很丑陋,“原始” .NET 方式看起来好多了
- 您必须按字符串命名事件,这很糟糕(如果您知道更好的方法,请联系我!)
- 它只能使用 EventHandler 的处理程序来处理事件
- 你变成了一个懒惰的开发者,不关心订阅
本质上,它们应该用于您的对象将在其存在的整个期间订阅的事件,并且仅在对象被释放时断开连接。对于其他一切,首选使用传统事件并手动注册/注销事件。
弱事件必须考虑两个问题:
- 弱事件允许订阅者订阅事件(消息),即使不知道引发事件的类的身份。在某些情况下,这可能是需要的,甚至是必要的。但是,在某些情况下,这可能会引入不必要的复杂性和一定程度的间接性,使代码在运行时更难管理或控制。
- 使用弱事件的主要缺点是它可能会鼓励开发人员忽略他们取消订阅事件(消息)的部分。在这种情况下,即使在订阅者“超出范围”之后,也可以调用事件处理程序。考虑一个没有显式取消订阅并且变为可垃圾回收但尚未被垃圾回收的订阅者。弱事件管理器将无法检测到该状态,因此它仍将调用该订阅者的事件处理程序。这可能会导致各种意想不到的副作用。
在弱事件模式很危险中查看更多详细信息。
请参阅使用 MvvMCross 消息传递插件作为弱事件管理器来说明此问题的源代码。
什么时候使用弱事件?
来自MSDN
监听事件可能导致内存泄漏
所以你应该使用弱事件来避免这些泄漏
每个暴露事件的类都使用它好吗?随意使用弱事件有什么副作用?
请参阅为什么 C# 中的事件实现默认不使用弱事件模式?. 从“强”事件中泄漏并不常见,弱事件会带来性能成本,并且在每种情况下都可能存在语义差异,滥用弱引用可能会导致事件间歇性地不触发(与滥用导致内存泄漏的正常事件)
可以避免的示例内存泄漏
静态类和单例在谈论内存泄漏时是恶棍,当它们获取对其他对象的引用时,它们将阻止对象被垃圾收集,因此,在应用程序的生命周期内泄漏对象,这是我遇到的一个例子需要弱引用以避免内存泄漏