In an AddHandler directive, you can use:
AddHandler MyControl.SomeEvent, AddressOf SomeMethod
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?
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.
Property stored As Class1
Sub Open() //Window1 event
dim c As new Class1
AddHandler self.KeyDown, WeakAddressOf c.handleKeyDown
stored = c
Sub Action() //Pushbutton1 event
stored = nil
Function handleKeyDown(sender As Object, key As String) As boolean
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
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.
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.