Form_Closed是否是删除事件处理程序的正确位置



我有一个程序集,它拖放了一个COM Interop VB 6.0文本编辑器,并将其用作.NET包装的控件。。。然后,在一个窗口窗体的新程序集中,我拖放上面的程序集并开始使用它,声明它的一个变量并为它分配事件处理程序,例如,如果Assmbley abvoe是namvedMyTextControl,那么在这个窗口窗体中,我有一个变量mytextcntrl和一些事件处理程序(如)

mytxtcntrl.TextEditor.ObjectDblClicked += new AxTextEditorLib._DTextEditorEvents_ObjectDblClickedEventHandler(ctlTEEditor_ObjectDblClicked);

所以现在Sholud我甚至担心用"-="删除这些事件处理程序?还是GC来处理?如果我应该手动操作,那么正确的操作位置是什么?我把它们放在Form_Closed部分,并运行了一个内存探查器,但没有任何效果。

只有当事件源对象超过事件订阅者时,才需要显式取消订阅事件。不这样做将保留对订阅对象的引用,防止它们被垃圾收集。

Winforms经过精心设计,避免了这种事故。您通常会在窗体或用户控件中编写一个事件处理程序来侦听子控件触发的事件。这些子控件的生存期与表单的生存期密切相关,当用户关闭表单时,它们都会同时被处理。垃圾收集器不会被这一点所困扰,而是会同时收集它们。

您的ActiveX控件符合此模式,它将是窗体的子控件,因此在窗体死亡的同时死亡。根本不需要明确的清理。

在一些角落的情况下,这将不会像所描述的那样起作用。一个经典的例子是,你自己在自己的代码中删除一个控件,但保持表单的活力。现在,应该取消订阅任何事件,以允许对该控件进行垃圾收集。最重要的是,您还必须在控件上显式调用Dispose(),以确保它的本机窗口被破坏。不这样做会产生永久性泄漏,即使垃圾收集器也无法解决,控件通过其窗口句柄保持活动状态。

第二种情况是SystemEvents类。它的事件是静态的,类对象一直存在到程序终止。如果您以可能在不终止应用程序的情况下关闭的形式使用其事件,则必须明确取消订阅。

不,你不应该。GC会处理它。你唯一需要担心"拖走"对象的地方是,当你使用实现IDisposable的类时,或者当你使用System.Runtime.InteropServices时。

相关内容

  • 没有找到相关文章

最新更新