AddressOf vs. WeakAddressOf in AddHandler

In an AddHandler directive, you can use:

AddHandler MyControl.SomeEvent, AddressOf SomeMethod

or

AddHandler MyControl.SomeEvent, WeakAddressOf SomeMethod

Using WeakAddressOf means that the handler gets removed as soon as the object is closed or goes out of scope. With AddressOf, you have to be sure to later use a RemoveHandler statement to remove the linkage.

So why would you not always want to use WeakAddressOf? Is there ever a time when you would want the event handler relationship to stay intact after an item is closed or gone away? It seems to me using the WeakAddressOf is always better. Yes? No?

1 Like

Iā€™m not 100% sure which way you mean by this, but a danger with WeakAddressOf in a AddHandler is then the handling object/delegate can go nil while the broadcasting object is still around to send that event.

If that happens thereā€™s still a ā€˜delegate thingā€™ in the handler bank so it calls it but itā€™s nil and the app crashes.

This code creates an object to handle the windows KeyDown event. Run and press a key to have it msgbox the ascii code. Press the button to nil the handling object then press a key again. For me it drops into the debugger with no stack.

[code]Window Window1

Property stored As Class1

Sub Open() //Window1 event
dim c As new Class1
AddHandler self.KeyDown, WeakAddressOf c.handleKeyDown
stored = c
End Sub

Sub Action() //Pushbutton1 event
stored = nil
End Sub

End Window

Class Class1
Function handleKeyDown(sender As Object, key As String) As boolean
MsgBox Str(Asc(key))
End Function
End Class[/code]

If youā€™re sure the weak delegate wonā€™t go nil while its a handler, thatā€™s fine. As long as you donā€™t refactor so itā€™s not :slight_smile:

Also, it appears a window will nil itā€™s controls when closing. So if your concern is cyclic links from control events that are implemented by window methods, well, you can use regular AddressOfs. When the control gets niled the cycle is broken and the window will go nil. But Iā€™m sure itā€™ll be advised to use RemoveHandler to leave no doubt.

Thanks, Will.

I understand your point above - how if you reference a method in a class and the class goes nil, you have a problem when using WeakAddress. In my case, Iā€™m typically adding handlers to objects in code that are not RectControls. So for example, Iā€™ve subclassed a TCPSocket and added some timers in the subclass. Timers need handlers to handle their action event so those are then implemented as methods in the socket. There is no ā€œclosingā€ of a TCPSocket as in a regular RectControl. Closing a socket just terminates the connection. It does not destroy the Socket object. So you have to set it to Nil when you want it closed. If you do that and you have a timer out there running code when you set the socket to Nil, then you have the opposite problem of what you described above. The timer code tries to execute but the object that itā€™s part of no longer exists and so you get errors.

So maybe the rule of thumb is:

1.) Use AddressOf when the handler may go nil
2.) Use WeakAddressOf when the object needing the handler may go nil

??

I think, for the socket and timers, you can use WeakAddressOf. If the socket goes nil then itā€™s cleaned up so the timers references drop to 0 and they get cleaned up and then no events are pumped and itā€™s all gone.

Could the timer fire just after the socket has been garbage collected but before the timer being collected? If so nil the timers in the sockets destructor so theyā€™re collected first. I doubt that could happen like that but I donā€™t know.

No. Garbage collection is instantaneous. I donā€™t think even a context switch can happen. But certainly no event loop.