事件处理程序是否停止发生垃圾回收?
如果我有以下代码:
MyClass pClass = new MyClass(); pClass.MyEvent += MyFunction; pClass = null;
pClass会被垃圾收集吗? 还是会在发生事件的时候继续运行呢? 为了允许垃圾收集,我需要执行以下操作吗?
MyClass pClass = new MyClass(); pClass.MyEvent += MyFunction; pClass.MyEvent -= MyFunction; pClass = null;
对于“将pClass垃圾收集”的具体问题:事件订阅对pClass(作为发布者)的集合没有任何影响。
对于一般的GC(特别是目标):取决于MyFunction是静态的还是基于实例的。
实例方法的委托(例如事件订阅)包含对实例的引用。 所以是的,一个事件订阅会阻止GC。 但是,只要发布事件的对象(上面的pClass)有资格收集,就不会成为问题。
请注意,这是单向的; 即如果我们有:
publisher.SomeEvent += target.SomeHandler;
那么“出版商”将保持“目标”活着,但“目标”不会让“出版商”活着。
所以不行:如果pClass将被收集,则不需要取消订阅听众。 但是,如果pClass长期存在(比使用MyFunction的实例长),那么pClass可以保持该实例的活动状态,因此如果希望收集目标,则需要取消订阅。
但是,由于这个原因,静态事件在与基于实例的处理程序一起使用时非常危险。
当一段内存不再被引用时,它就成了垃圾收集的候选对象。 当你的类的实例超出范围,它不再被你的程序引用。 它不再使用,因此可以安全地收集。
如果你不确定会不会收集到一些问题,请问下面的问题:是否还有其他的参考? 事件处理程序由对象实例引用,而不是相反。
是的,pClass将被垃圾收集。 事件订阅并不意味着对pClass存在任何引用。
如此否,你将不必分离处理程序为了pClass被垃圾收集。
pClass
将被垃圾收集。 但是,如果上面的代码片段在另一个类中,那么如果不将pClass
设置为null
,则该类的实例可能不会被清除。