C#如何取消订阅特定事件中的所有事件处理程序?

Adi*_*rda 14 c# events memory-leaks

是否有一种简单的方法来迭代订阅给定事件的处理程序?我的问题是客户订阅但忘记取消订阅,因此发生内存泄漏.我需要一种方法让一个对象在Dispose方法中断开其事件的所有处理程序,这样就不会发生泄漏 - 至少不是因为事件.

And*_*zub 12

将null设置为您的事件: MyEvent = null;

但是让客户取消订阅您的活动真的更好.

  • 实际上,如果你在宣布事件的类里面,它是可能的. (9认同)
  • @Mateusz:如果没有人订阅事件字段,则事件字段为空,触发事件的代码在访问事件之前始终应该进行空检查 (4认同)

Tom*_*cek 9

另一种方法是使用所谓的"弱委托"模式.使用此技术时,事件仅引用客户端WeakReference,但不会将其保留在内存中.当客户端不再从应用程序的其他部分引用时,将对其进行垃圾回收(并且在收集客户端时也可以自动取消注册处理程序).

这通常用于解决客户"忘记"取消订阅.NET事件的问题,因此听起来这可能非常适合您的问题.


Ale*_*x F 7

仅当另一个对象(侦听器)在对象(事件源)之前死亡时才会发生内存泄漏.在这种情况下,事件源仍然保留对侦听器的引用,这会阻止收集侦听器.当事件源死亡时,也可以收集未订阅的侦听器.

如果事件源在侦听器之前死亡,则这不会阻止稍后收集侦听器,此时对其的所有其他引用都设置为null.

这意味着,事件源Dispose方法不正确的地方来解决这个问题.它可以仅在侦听器代码中解决.简单地说,除了要求客户编写干净的代码之外,你什么也做不了.