c#控件扫除前需要单独解绑其事件属性上绑定的函数吗?为什么

c#控件清除前需要单独解绑其事件属性上绑定的函数吗?为什么?
近日,看到一些项目代码中,在清除控件前,总会将其事件属性上绑定的函数专门清除掉,然后,再将该控件设置为nulll。很是不解,控件就是个对象,已经将对象设置为null了,其事件属性上绑定的函数自然就没了,为何还需专门清理?
代码举例如下:
                  
  tabPageManager.e_OnGatherPublishCompleted -= new OnGatherPublishCompleted(tabPageManager_e_OnGatherPublishCompleted);
tabPageManager = null;

------解决思路----------------------
设置为null只是解除了一个引用,不代表控件被销毁。控件使用了非托管资源,有析构方法,如果不主动Dispose,等到所有引用都解除,GC会把它放到析构队列,最后执行析构之后才是真正销毁。这个过程可能很久。如果确定要销毁,应该主动调用Dispose,而不是设置成null。

你看到的代码里,如果是这个控件在别处还有使用,只是这里不再需要,那么解绑是应该的。如果把这个引用当作一个标志,自己的逻辑需要判断它,那么设置null是合理的。如果这个代码是属于销毁的逻辑,那么设置null不必要。

关于事件绑定,如果把短生命周期的对象挂接在长生命周期的对象的事件上,不解绑的话会导致这些短生命周期的对象无法释放,直到绑定的长生命周期对象释放,它们才能释放。所以一般规则是,短生命周期的对象销毁的逻辑里需要把挂接在长生命周期的对象的事件解绑。否则会造成内存泄漏。

而关于设置null这个话题,这里有详细的分析。
------解决思路----------------------
事件本身就在该对象内,没必要再特地解绑了。如果事件绑定的处理方法在别的类中,那么解绑一下,是有必要的
初衷是避免有引用在,导致垃圾回收无法回收资源。
------解决思路----------------------
引用:
事件本身就在该对象内,没必要再特地解绑了。如果事件绑定的处理方法在别的类中,那么解绑一下,是有必要的
初衷是避免有引用在,导致垃圾回收无法回收资源。


引用自身方法是不需要特地去释放的,如form.Designer里面的事件绑定,你也没见到有解绑的操作。
需要手动解绑除了上面说的引用了其它类中的方法,还有是用自身方法去注册了一个全局的事件。如果注册了Application.ApplicationExit事件。

另:在Dispose的时候写tabPageManager = null;其实是没必要的,详见《编写高质量代码:改善C#程序的151个建议》第4章。
Release编译时IL是直接忽略这段代码的。