Uneventful

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.