当前位置:  开发笔记 > 编程语言 > 正文

事件处理程序是否阻止垃圾收集发生?

如何解决《事件处理程序是否阻止垃圾收集发生?》经验,为你挑选了3个好方法。

如果我有以下代码:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

pClass会被垃圾收集吗?或者它会在它们发生的时候仍然停止发射?我是否需要执行以下操作才能进行垃圾回收?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;

Marc Gravell.. 199

对于特定问题"将pClass收集垃圾":事件订阅对pClass(作为发布者)的集合没有影响.

对于一般的GC(特别是目标):它取决于MyFunction是静态的还是基于实例的.

实例方法的委托(例如事件订阅)包括对实例的引用.所以,是的,事件订阅将阻止GC.但是,只要发布事件的对象(上面的pClass)有资格进行收集,这就不再是一个问题.

请注意,这是单向的; 即如果我们有:

publisher.SomeEvent += target.SomeHandler;

然后"发布者"将保持"目标"活着,但"目标"不会让"发布者"保持活力.

所以没有:如果要收集pClass,则无需取消订阅听众.但是,如果pClass是长寿命(比MyFunction的实例更长),然后pClass可以保持该实例活着,所以它如果要收集目标有必要取消.

但是,出于这个原因,静态事件与基于实例的处理程序一起使用时非常危险.



1> Marc Gravell..:

对于特定问题"将pClass收集垃圾":事件订阅对pClass(作为发布者)的集合没有影响.

对于一般的GC(特别是目标):它取决于MyFunction是静态的还是基于实例的.

实例方法的委托(例如事件订阅)包括对实例的引用.所以,是的,事件订阅将阻止GC.但是,只要发布事件的对象(上面的pClass)有资格进行收集,这就不再是一个问题.

请注意,这是单向的; 即如果我们有:

publisher.SomeEvent += target.SomeHandler;

然后"发布者"将保持"目标"活着,但"目标"不会让"发布者"保持活力.

所以没有:如果要收集pClass,则无需取消订阅听众.但是,如果pClass是长寿命(比MyFunction的实例更长),然后pClass可以保持该实例活着,所以它如果要收集目标有必要取消.

但是,出于这个原因,静态事件与基于实例的处理程序一起使用时非常危险.


好吧,如果问题是"将pClass收集垃圾",那么答案"它取决于是否......"实际上并不正确.它不依赖于任何东西,因为Marc自己进一步指出了这一点.

2> Tor Haugen..:

是的,pClass将被垃圾收集.事件订阅并不意味着pClass存在任何引用.

所以不,你不必分离处理程序,以便pClass被垃圾收集.



3> 小智..:

一段内存不再被引用的那一刻它就成了垃圾收集的候选者.当您的类的实例超出范围时,您的程序将不再引用它.它不再使用,因此可以安全地收集.

如果你不确定某些东西会被收集,请问自己以下问题:是否仍然存在对它的引用?事件处理程序由对象实例引用,而不是相反.

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有