我在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
为什么会这样?
答案 0 :(得分:4)
看起来你已经做了很好的发现!根据Microsoft文档, RaiseEvent Statement ,
不应该在构造函数中引发非共享事件 声明它们的类。虽然这样的事件不会引起 运行时错误,它们可能无法被关联事件捕获 处理程序。如果需要,请使用
Shared
修饰符创建共享事件 从构造函数中引发事件。
换句话说,微软表示你不应该做你正在做的事情 - 如果必须,你也应该使用共享事件。
在查看其他来源时,我会说AddHandler
和Handles
之间的差异是语法糖的问题。您可能希望了解如何在C#中完成事件以获得更多洞察力(例如 C# Events )。 Handles
与WithEvents
结合使用,作为类的实例自动订阅事件的方式(在C#和+=
中使用AddHander
显式完成在VB.NET中。)
您的显式AddHandler
似乎确保事件连接在RaiseEvent
之前就位,因此它可以按您的需要工作。我只能猜测,如果没有这个,那些事件连接还没有完成 - 也就是说,它没有用,因为编译器编写者无论设计模式如何编译器都会在后台插入执行相当于AddHandler的代码视为合适。鉴于他们对此有所警告,设计师似乎很清楚这种可能的后果。