WithEvents(句柄)与AddHandler之间的区别

时间:2012-04-12 12:43:27

标签: vb.net event-handling

我在Handles中搜索了关键字AddHandler而不是VB.NET的使用区别,但我无法解释为什么此代码不起作用..

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

为什么会这样?

1 个答案:

答案 0 :(得分:4)

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

  

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

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

在查看其他来源时,我会说AddHandlerHandles之间的差异是语法糖的问题。您可能希望了解如何在C#中完成事件以获得更多洞察力(例如 C# Events )。 HandlesWithEvents结合使用,作为类的实例自动订阅事件的方式(在C#和+=中使用AddHander显式完成在VB.NET中。)

您的显式AddHandler似乎确保事件连接在RaiseEvent之前就位,因此它可以按您的需要工作。我只能猜测,如果没有这个,那些事件连接还没有完成 - 也就是说,它没有用,因为编译器编写者无论设计模式如何编译器都会在后台插入执行相当于AddHandler的代码视为合适。鉴于他们对此有所警告,设计师似乎很清楚这种可能的后果。