【问题标题】:Is there any way to clear subscription to an event in VB.NET?有没有办法清除对 VB.NET 中事件的订阅?
【发布时间】:2009-11-10 10:33:50
【问题描述】:

在 C# 中,我习惯于在 Dispose() 中清除对我的自定义事件的每个订阅,以避免订阅者忘记取消订阅我的事件而导致内存泄漏。

这很简单,只需调用MyEvent = null,因为C# 编译器会自动生成一个委托字段。不幸的是,在 VB.NET 中,似乎没有简单的方法可以做到这一点。我想出的唯一解决方案是编写一个Custom Event,添加调用Delegate.Combine / Delegate.Remove 的自定义添加和删除处理程序,这基本上是C# 编译器所做的。但是,为了能够清除订阅而必须对每个事件都执行此操作对我来说似乎有点“矫枉过正”。

有没有人有其他想法来解决这个问题?谢谢。

【问题讨论】:

    标签: vb.net events subscription


    【解决方案1】:

    在 VB.Net 中完全一样。每个事件的编译器automatically creates a delegate field,就像 C# 编译器一样,但在 VB 中该字段是隐藏的。但是,您可以从代码中访问该变量 - 它始终命名为 XXXEvent,其中 XXX 是事件名称。

    因此您可以轻松清除对事件的订阅,就像在 C# 中一样:

    Public Class Class1
      Implements IDisposable
      Event MyEvent()
    
      Sub Clear() Implements IDisposable.Dispose
        Me.MyEventEvent = Nothing ' clear the hidden variable '
      End Sub
    End Class
    

    我也在想应该可以使用反射来自动找到所有隐藏的委托变量,并清除它们。那么它们就不必在Clear 方法中列出。

    【讨论】:

    • 谢谢!没有看到那个文档部分,非常有帮助。在使用反射时,将一些变量设置为 null 似乎很繁重;但在调试时断言每个字段都正确设置为 null 非常有用。
    • 我在想也许有一个通用方法 ClearAllSubscriptions 使用反射来处理任何类型:那么你在 Clear 方法中所需要的就是ClearAllSubscriptions Me
    【解决方案2】:

    我对 VB.NET 的了解很模糊,但是 AddHandler / RemoveHandler 呢?

    【讨论】:

    • AddHandler/RemoveHandler 是 C# 中 += 和 -= 的 VB.NET 等价物。因为我不认识每个订阅者(除非我自定义事件),所以我不能删除每个订阅者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2016-01-06
    • 2010-09-14
    • 2021-11-01
    相关资源
    最近更新 更多