Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between WithEvents (Handles) vs AddHandler

I've searched for the difference about the use of the keyword Handles instead of AddHandler, in VB.NET, but I'm unable to explain why this code doesn't work..

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

Well, this code never respond to the events, but if I uncomment the followin line, the code works and the messagebox appear...

'AddHandler MainThreadFinished, AddressOf Me.MyEvents_ThreadFinished

Why does this happen?

like image 481
Katte Avatar asked Aug 25 '26 23:08

Katte


1 Answers

It looks like you've made a fine discovery! Per Microsoft documentation, RaiseEvent Statement,

Non-shared events should not be raised within the constructor of the class in which they are declared. Although such events do not cause run-time errors, they may fail to be caught by associated event handlers. Use the Shared modifier to create a shared event if you need to raise an event from a constructor.

In other words, Microsoft says you shouldn't be doing what you're doing - and if you must, to use shared events.

In looking through other sources, I would say that the difference between AddHandler and Handles is a matter of syntactic sugar. You may want to look into how events are done in C# for more insight (such as in C# Events). Handles is used in conjunction with WithEvents as a way for an instance of a class to automatically subscribe to events (which is otherwise explicitly done with += in C# and with AddHander in VB.NET).

It would seem that your explicit AddHandler ensures that the event hookups are in place before the RaiseEvent, and so then it works as you wanted. I can only guess that without that, those event hookups weren't yet done - that is, it didn't work because of however the compiler inserts the code that performs the equivalent of AddHandler behind the scenes, by whatever design pattern the compiler writers deemed as appropriate. It would seem that the designers were well aware of this possible consequence, given their warning about this.

like image 115
rskar Avatar answered Aug 27 '26 18:08

rskar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!