通过WeakReference实现事件处理是一个好习惯,如果该事件是唯一持有引用的东西,并且我们需要对象进行垃圾回收?
作为对此的论据:
有人说如果你订阅某些东西,你有责任取消订阅,你应该这样做。
答案 0 :(得分:14)
尽可能养成从事件中取消订阅的习惯是好的,但有时候没有明显的“清理”方法可以完成。我们最近在此主题上发布了blog article;它包含的方法可以轻松订阅具有WeakReference的事件。
答案 1 :(得分:9)
弱委托模式应该在CLR中存在。正常事件表现出“在你活着时通知我”的语义,而我们经常需要“在我活着时通知我”。只是在WeakReference上有委托是错误的,因为委托也是一个对象,即使当接收者仍然存在并且有传入的引用时,委托本身只被所述WeakReference引用并将立即收集。有关实施的示例,请参阅this old post。
答案 2 :(得分:6)
弱引用本身就没有解决问题,因为委托持有引用。在Prism(www.microsoft.com/compositewpf)附带的复合应用程序库中,有一个可以从源中提取的WeakDelegate类。 WeakDelegate基本上是反射并且仅在一段时间内创建一个委托然后释放它,从而没有任何指针。在CAL中,它由EventAggregator类使用,但您可以自由地将其用于自己的使用,因为它在MS-PL下。
答案 3 :(得分:-3)
虽然您的建议解决了一组问题(事件参考管理和内存泄漏防护),但它可能会引发一系列新问题。
我可以看到的一个问题是在事件处理过程中如果源对象被垃圾收集(因为它只使用弱引用持有),任何访问源对象的代码都将导致空引用异常。您可以争辩说,事件处理程序应该不访问源对象,或者它必须具有强引用,但可以认为这可能是一个比您首先尝试解决的问题更糟糕的问题。