After reading the post about events and AddHandler and tracking references and hanging objects, you might be a little
concerned about using events at all, maybe because of the added code or the housekeeping. If so, you can
consider another way of doing event-type behavior using Delegates.
Delegates can be used many different ways. This particular way might be a little different than what you’ve
previously seen. The general concept is to keep a variable holding all the delegates to be called for an
event. This variable (as a delegate itself) can be invoked at any time, and more importantly, can be cleared
at any time.
Reusing some old code from the previous post, we still have our HangingObject class and we now have this method to
build the objects and call their internal method:
Private Sub UsingDelegate()
Dim o As HangingObject
HelloList = [Delegate].RemoveAll(HelloList, HelloList)
For i As Integer = 1 To 5
o = New HangingObject
HelloList = [Delegate].Combine(HelloList, New SayHelloDelegate(AddressOf o.SayHello))
Next
HelloList.DynamicInvoke(Nothing)
End Sub
And at the form level, we have the delegate sub definition and the delegate variable holding all the calls.
Public Delegate Sub SayHelloDelegate()
Dim HelloList As [Delegate] = Nothing
So what’s different? We’ve changed the event declaration to a Delegate Sub declaration; we’ve added a variable
to hold all the event subscriptions; instead of using AddHandler, we use Delegate.Combine to register the event
subscription; and instead of RaiseEvent, we use DynamicInvoke. There’s not much more or less, but everything
is different. The list of subscribers is accessible now through the variable HelloList, which is a huge
benefit.
The two interesting parts of this code are the shared methods on the Delegate class: Combine and RemoveAll. The
delegate itself (HelloList) contains a list of invocation targets, similar to subscribers of an event. The
Combine method merges the specific SayHelloDelegate invocation list with the generic HelloList invocation list,
resulting in one list of all the targets. Calling the DynamicInvoke method performs a .Invoke on all the
delegates in the invocation list. Simple and magical.
However, because HelloList is declared at the form level, it persists between calls and can suffer the same issues as
the AddHandler method. The nice thing is that you can clear the invocation list by using RemoveAll, or you can
just set the variable to Nothing. If HelloList was defined within the method instead of the form, it would be
cleared at the end of the method, unlike the AddHandler method, where the event is declared at the form level.
It’s good to know a lot of different ways to do something, just in case. Another tool in the coding toolbox.