在哪里“销毁”VB.NET 类中的处理程序?

ser*_*hio 1 .net vb.net events event-handling addhandler

我有一些MyUserControl引发事件的类(用户控件)。

我以一种形式使用它MyForm,因为某些原因我被迫使用AddHandler而不是WithEvents<>Handles配对。

AddHandlerMyForm_Load方法中使用了s 。

现在。添加处理程序没问题,现在的问题是在哪里删除这个处理程序。应该在FinalizeMyForm的方法中完成吗?à la

Protected Overrides Sub Finalize()
  RemoveHandler _myCtrl.Action1Performed, AddressOf MyControl_Action1Performed  
  RemoveHandler _myCtrl.Action2Performed, AddressOf MyControl_Action2Performed  
  RemoveHandler _myCtrl.Action3Performed, AddressOf MyControl_Action3Performed  
End Sub
Run Code Online (Sandbox Code Playgroud)

Cod*_*ray 5

当容器控件(例如您的表单)被释放时,它的所有事件处理程序都将被自动删除和释放。这种清理会自动发生,因为您的用户控件及其容器形式都不再存在。

您真正需要担心调用的唯一时间RemoveHandler是,如果您将事件处理程序连接到预期寿命比其容器长得多的对象。在这种情况下,可能会造成内存泄漏,因为只要订阅了该处理程序,就无法对该对象进行垃圾回收。您可以在 Tess Ferrandez 的博客上阅读更全面的案例研究。如果两个对象同时“超出范围”,这不是问题。

编辑:如果您仍然觉得您绝对需要删除处理程序(也许您有强迫症?),您可以继续使用表单的Dispose方法进行操作。纯粹主义者可能IDisposable会拒绝使用像这样的东西,但您不会看到任何不良结果。不过,您确实要确保不Finalize为此实现该方法。没有任何意义:在没有对对象的强引用之前,终结器方法不会被调用,但调用失败的唯一可能危害RemoveHandler是容器将持有对该对象的引用的时间超过必要的时间。您试图删除Finalize方法中的事件处理程序是在自欺欺人。

还请记住,您在何处执行此操作实际上并不重要,因为AddHandler/的目的RemoveHandler是允许您动态添加和删​​除事件处理程序。你可以在你想要的代码中的任何地方调用它们。