WithEvents (Handles) 与 AddHandler 之間的區別



我已经在 VB.NET 中搜索了有关使用关键字句柄而不是AddHandler的区别,但我无法解释为什么这段代码不起作用。

Imports System.Threading
Public Class MyClass_EventArgs
    Inherits System.EventArgs
End Class
Public Class MyClass
    Public Event MainThreadFinished(ByVal sender As Object, ByVal e As MyClass_EventArgs)
    Private WithEvents MyEvents As MyClass
    Private trd As Thread
    Public Sub New()
        'AddHandler MainThreadFinished, AddressOf Me.MyEvents_ThreadFinished
        trd = New Thread(AddressOf mainThread)
        trd.IsBackground = True
        trd.Start()
        RaiseEvent MainThreadFinished(Me, Nothing)
    End Sub
    Protected Overrides Sub Finalize()
        trd.Abort()
    End Sub
    Protected Sub MyEvents_ThreadFinished(ByVal sender As Object, ByVal e As MyClass_EventArgs) _
                Handles MyEvents.MainThreadFinished
        MessageBox.Show("AAA")
    End Sub
    Private Sub mainThread()
        RaiseEvent MainThreadFinished(Me, Nothing)
    End Sub
End Class

好吧,这段代码从不响应事件,但是如果我取消注释以下行,代码就可以工作并且会出现消息框......

'AddHandler MainThreadFinished, AddressOf Me.MyEvents_ThreadFinished

为什么会这样?

看来你已经有了很好的发现!根据Microsoft文档,RaiseEvent Statement

不应在 在其中声明它们的类。虽然此类事件不会导致 运行时错误,关联事件可能无法捕获它们 处理器。如果需要,请使用 Shared 修饰符创建共享事件 从构造函数引发事件。

换句话说,Microsoft说你不应该做你正在做的事情 - 如果你必须,使用共享事件。

在查看其他来源时,我会说AddHandlerHandles之间的区别是句法糖的问题。你可能想要了解事件在 C# 中的完成方式,以便更深入地了解(例如在 C# 事件中)。 HandlesWithEvents 结合使用,作为类实例自动订阅事件的一种方式(否则,在 C# 中使用 += 显式订阅事件,在 VB.NET 中使用 AddHander 显式订阅事件)。

似乎您的显式AddHandler可确保事件连接在RaiseEvent之前就位,因此它可以按您想要的方式工作。我只能猜测,如果没有它,这些事件连接还没有完成 - 也就是说,它不起作用,因为编译器在幕后插入了等效于 AddHandler 的代码,无论编译器编写者认为合适的设计模式。鉴于他们对此的警告,设计师似乎很清楚这种可能的后果。

相关内容

  • 没有找到相关文章

最新更新