弱引用和事件处理
本文关键字:事件处理 引用 | 更新日期: 2023-09-27 17:47:22
如果该事件是唯一保存引用并且我们需要对对象进行垃圾回收,那么通过 WeakReference 实现事件处理是否是一种好的做法?
作为对此的论据:
人们说,如果你订阅了某些东西,你有责任取消订阅,你应该这样做。
尽可能养
成取消订阅事件的习惯是件好事,但有时没有明显的"清理"方法可以做到。我们最近发布了一篇关于这个主题的博客文章;它包括一些方法,可以轻松地使用弱引用订阅事件。
弱委托模式应该存在于 CLR 中。正常事件表现出"在你活着的时候通知我"的语义,而我们经常需要"在我还活着的时候通知我"。仅仅在弱引用上拥有委托是错误的,因为委托也是一个对象,即使接收者仍然活着并且有传入的引用,委托本身也只会被所述弱引用引用,并且会立即被收集。有关实现示例,请参阅此旧帖子。
弱引用本身,不能解决问题,因为委托持有引用。在 Prism (www.microsoft.com/compositewpf) 附带的复合应用程序库中,有一个可以从源代码中提取的 WeakDelegate 类。弱委托基本上是反射,只创建一个委托片刻,然后释放它,因此不持有任何指针。在 CAL 中,它由 EventAggregator 类使用,但您可以自由地将其删除以供自己使用,因为它在 MS-PL 下。
虽然您的建议解决了一组问题(事件引用管理和内存泄漏预防),但它可能会带来一组新问题。
我可以看到的一个问题是,在事件处理过程中,如果源对象被垃圾回收(因为它仅使用弱引用保存),则访问源对象的任何代码都将导致空引用异常。您可以争辩说事件处理程序不应该访问源对象,或者它必须具有强引用,但可以争辩说,这可能是一个比您首先尝试解决的问题更糟糕的问题。