Hold a reference to a timer

Is it necessary to hold a reference to a timer?

For instance, in a thread, if I make a new timer (active and a period of 1) without holding onto it as a property, will that timer sometimes not fire?

[quote=19471:@Stephen Dodd]Is it necessary to hold a reference to a timer?

For instance, in a thread, if I make a new timer (active and a period of 1) without holding onto it as a property, will that timer sometimes not fire?[/quote]

You should hold onto it until it’s fired.

I think it will not fire. If you don’t retain it in a property it will be destroyed by the garbage collector.

I thought you’d say that. Oh, well. Off to make some code more complex.

Why complex? if it’s a class, just declare a property and use AddHandler to wire the Action event to a method.

Yeah, creating a circular reference will work for this – just be sure to use RemoveHandler and then set the timer to Nil from the event handler. Probably should comment that you’re intentionally creating a circular reference just so that you don’t think it’s a leak when you come back to it later.

You don’t need to RemoveHandler (unless I misunderstand the linkage being made). This class/code will show a MsgBox after 3 seconds and ObjectCount returns to it’s previous value. Simply make the self cycle when it starts and nil it when it stops.

[code]Class SelfSustainingTimer inherits Timer

Private selfCycle As SelfSustainingTimer //property

Sub Mode(assigns m As Integer) //override method
Timer(self).Mode = m
if (m = 1 or m = 2) then selfCycle = self else selfCycle = nil
End Sub

Sub Action() //event handler
RaiseEvent Action
if Mode = 1 then selfCycle = nil
End Sub

Sub Action() //event definition

End Class

Sub PushButton1.Action()
dim t As new SelfSustainingTimer
t.Period = 3000
AddHandler t.Action, AddressOf foo
t.Mode = Timer.ModeSingle
End Sub

Sub foo()
Msgbox “ok”
End Sub[/code]

Must remember to use AddHandler more often. Thanks guys!

In this case, I wanted something a bit more self contained so I made a module so that I can call

MsgBoxThreadSafe “Hello World”

See my separate post about it

https://forum.xojo.com/2963-thread-safe-msgbox-example

Why RemoveHandler and setting timer to Nil?
If the Timer is a property of the class, destroying the class should also destroy the timer and the the handler. Right?

If the Timer is a property of the class and the Timers action is linked to a method of that class then they won’t go away on their own. In this case you’d have to nil the Timer property or removehandler.

If the handler is wired using WeakAddressOf (as it should for class instances) it should not create a circular reference.

Good point. I keep forgetting about that option.

I must be missing something here. So, you make a link to something to make it undisposable when it goes out of scope. Then you say “this link is of the unretainable kind”. So it should be disposable again?

Using WeakAddressOf you get a weakRef to the object, so it’s not directly referenced (no circular ref).
Then, when I destroy the class, the Timer is destroyed since there are no other references to it.
Still the handler remains wired to a void reference, but it’s a temporary situation, just as the handler method is destroyed too.

I don’t understand what you mean here, sorry.

You should definitely still call RemoveHandler. Otherwise nobody else will ever be able to call AddHandler for that event again (multiple handlers aren’t supported at this time).

And here’s a fantastic overview of how reference counting comes into play with AddressOf, delegates, and AddHandler:
AddHandler and reference counts

Very handy explanation, thanks Joe.

Btw, using AddHandler with WeakAddressOf for a method of a class, do I still need to call RemoveHandler?
I think not, since when the instance will destroy, it will also destroy the handler and nobody need again to wire to it with AddHandler.
But please correct me if I’m wrong.

[quote=20188:@Massimo Valle]Very handy explanation, thanks Joe.

Btw, using AddHandler with WeakAddressOf for a method of a class, do I still need to call RemoveHandler?
I think not, since when the instance will destroy, it will also destroy the handler and nobody need again to wire to it with AddHandler.
But please correct me if I’m wrong.[/quote]

Sorry in advance if I’m misunderstanding the question. The way events work is that there’s essentially an internal array of event handlers. When you implement an event in the IDE, the event handler’s slot is filled with that handler. When you all AddHandler, it checks to see if the slot is full. If it is, an exception is raised. If it isn’t, the handler passed is shoved in there.

If you don’t call RemoveHandler, the slot remains full – regardless of whether or not it’s a WeakRef-based delegate or not.

Joe, I’ll try to explain myself better, sorry in advance for my english.

I have a class, where I define a Timer property and wire its Action event to a (private) method called MyTimerActionHandler of the same class with AddHandler(MyTimer.Action, WeakAddressOf MyTimerActionHandler).

At one point I instantiate the class, the instance make its work, then it go out of scope. The Timer is destroyed and so the MyTimerActionHandler method. In that case (perhaps in Destructor) should I still call RemoveHandler?

I dealt with this several years ago… I think before add handler was a introduced.

http://mysite.verizon.net/vzezdg8x/id4.html

[quote=20250:@Karen Atkocius]I dealt with this several years ago… I think before add handler was a introduced.

http://mysite.verizon.net/vzezdg8x/id4.html[/quote]

Cool, however I don’t agree on having instances living somewhere without having a reference to it. The only exception could be a window instance, but even with that I have some doubt.
Also, shadowing of properties could be very dangerous.