Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Thu Dec 12, 2019 10:13 pm
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 8:42 am 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
Hello,

just a quick question about timer objects. Let's say I create the following timer object within the constructor of a networking class (e.g. HTTPSocket):

MyTimer = New Timer
MyTimer.Enabled = TRUE
MyTimer.Mode = Timer.ModeMultiple
MyTimer.Period = 100

AddHandler MyTimer.Action, AddressOf MyTimerAction

So, the function MyTimerAction is executed every 100 milliseconds. In my example, MyTimerAction does nothing more than comparing two numbers and if these are exceeding a given limit, the timer is disabled (MyTimer.Enabled = FALSE), a function from a module is called and the network object is closed (in exactly this order).

I'm unsure if 100 milliseconds is a sufficient value, because it must be avoided that the timer calls MyTimerAction again before it becomes disabled within MyTimerAction.

I have tested this on two computers, and it works without problems. But I'm still a little bit concerned about it. What do you think, how long does it take to compare two numbers and execute an if/then condition ?

Any thoughts are appreciated.

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 9:17 am 
Offline
User avatar

Joined: Sun Aug 05, 2007 10:46 am
Posts: 4931
Location: San Diego, CA
100 milliseconds is an ETERNITY

_________________
Dave Sisemore
iMac I7[2012], OSX Mountain Lion 10.8.3 RB2012r2.1
Note : I am not interested in any solutions that involve custom Plug-ins of any kind


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 9:44 am 
Offline

Joined: Sat Jul 16, 2011 2:45 pm
Posts: 76
Real Studio should be getting it's timer events off the main message queue and executing it from the main thread, so it shouldn't be possible for it to fire a second time before the first one has returned - if anything the first one will just delay /block the execution of the second timer event.

I don't think timers are in any way threaded (by the OS callback version or in RS) so to get that sort of behavior you would have to create two threads for the same function that execute within a certain time interval.

So your code should be fine.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 9:55 am 
Offline
User avatar

Joined: Sun Aug 05, 2007 10:46 am
Posts: 4931
Location: San Diego, CA
Yes it is quite possible ...

Consider this

you set your timer to interval X
in the Timer Action you call Method ABC
Method ABC takes 3X to complete
the timer WILL fire again even though ABC has not completed..... This will result in ABC NOT completing and starting again
as a matter of fact ABC will NEVER complete as it will be always be interrupted by the timer

This is a situation I have run across numerous times.

The "fix" is easy however.... put a "BUSY" flag at the beginning of ABC... modify the timer event to NOT call ABC if that flag is set. Reset the flag at the end of ABC

Now this is a simplified example,.... because obviiously if that is all the time did, you'd simply expand the interval

But you may have cases where the Timer calls various methods depending on the circumstances.



If it were getting the timer events from the message queue, there would be NO WAY to insure that interval was anywhere near accurate, as you cannot know the execution time of other messages in the queue

_________________
Dave Sisemore
iMac I7[2012], OSX Mountain Lion 10.8.3 RB2012r2.1
Note : I am not interested in any solutions that involve custom Plug-ins of any kind


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 11:05 am 
Offline
Site Admin
User avatar

Joined: Tue May 06, 2008 1:07 pm
Posts: 1464
Location: NotEvenOnTheMap, CT
DaveS wrote:
Yes it is quite possible ...

Consider this

you set your timer to interval X
in the Timer Action you call Method ABC
Method ABC takes 3X to complete
the timer WILL fire again even though ABC has not completed..... This will result in ABC NOT completing and starting again
as a matter of fact ABC will NEVER complete as it will be always be interrupted by the timer

This is a situation I have run across numerous times.

The "fix" is easy however.... put a "BUSY" flag at the beginning of ABC... modify the timer event to NOT call ABC if that flag is set. Reset the flag at the end of ABC

Now this is a simplified example,.... because obviiously if that is all the time did, you'd simply expand the interval

But you may have cases where the Timer calls various methods depending on the circumstances.



If it were getting the timer events from the message queue, there would be NO WAY to insure that interval was anywhere near accurate, as you cannot know the execution time of other messages in the queue

This is wrong. A Timer is NOT guaranteed to be accurate. You will not receive another Action event until the first completes. The only exception would be if you're doing something funny with threads, but even then, I'm having a hard time thinking up a scenario where this would be possible.

_________________
Thom McGrath - @tekcor
Web Framework Architect, Real Software, Inc.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 11:39 am 
Offline
User avatar

Joined: Sun Aug 05, 2007 10:46 am
Posts: 4931
Location: San Diego, CA
Well I'll be.... I just tested it... and you are correct...

However.... I HAVE seen (and had to work around) situations where the timer fired every interval regardless..

And no threads were involved.

_________________
Dave Sisemore
iMac I7[2012], OSX Mountain Lion 10.8.3 RB2012r2.1
Note : I am not interested in any solutions that involve custom Plug-ins of any kind


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 11:47 am 
Offline
Site Admin
User avatar

Joined: Tue May 06, 2008 1:07 pm
Posts: 1464
Location: NotEvenOnTheMap, CT
DaveS wrote:
Well I'll be.... I just tested it... and you are correct...

However.... I HAVE seen (and had to work around) situations where the timer fired every interval regardless..

And no threads were involved.

I'm sorry to sound harsh, but it's just not possible. Timers fire on the Main thread, and thread code is procedural. What you're suggesting is that code execution jumps forward and backward in the thread, which is an terrifying proposition.

I'm not sure what behavior you were seeing, but overlapping Timers, especially without threads, was not the cause. I'm sure there is some other explanation.

_________________
Thom McGrath - @tekcor
Web Framework Architect, Real Software, Inc.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 12:14 pm 
Offline

Joined: Sat Jul 16, 2011 2:45 pm
Posts: 76
Quote:
If it were getting the timer events from the message queue, there would be NO WAY to insure that interval was anywhere near accurate, as you cannot know the execution time of other messages in the queue
No timer can be considered accurate for this very reason. You would have to physically accommodate for every running process on the system and micro manage execution based around timer requirements based on the underlining function execution times in order to make it "accurate" which is realistically impossible to do for unprivileged software /user desktops.

However, the timer would be provided by the OS in order to maintain the highest level of accuracy and, as far as I know this is done via two methods - the main message chain or a dedicate Timer callback function, both of which should class as on the main thread.

A framework implementation would be less accurate and wasteful in resources as the OS will be using hardware level interrupts to provide it's timer mechanism.


DaveS wrote:
you set your timer to interval X
in the Timer Action you call Method ABC
Method ABC takes 3X to complete
the timer WILL fire again even though ABC has not completed..... This will result in ABC NOT completing and starting again
as a matter of fact ABC will NEVER complete as it will be always be interrupted by the timer

This is a situation I have run across numerous times.

The "fix" is easy however.... put a "BUSY" flag at the beginning of ABC... modify the timer event to NOT call ABC if that flag is set. Reset the flag at the end of ABC

Now this is a simplified example,.... because obviiously if that is all the time did, you'd simply expand the interval

But you may have cases where the Timer calls various methods depending on the circumstances.
Timer should not fire again unless the action event of that timer spawns a thread, in which case technically your timer event has returned and a thread is entirely independent of that process. While I don't know the specifics on the OS level implementation, but I'm pretty sure you have to return the message back to the OS too, so the queue will never be filled up with 100s of identical timer events in case execution was prolonged.

if I made a 1ms timer that, lets say opened up a new window and else where I had a function that never returned back to the main loop, that timer event should never fire as it will be blocked - if it did this would imply timers are threaded and RS should be advertising the need to be thread safe (critical sections, etc) but then this is contrary to using them to update the interface instead of using a thread, that single statement alone implies they are on the main thread execution


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 1:06 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
Thank you for your comments and this interesting discussion. :-)

> 100 milliseconds is an ETERNITY

I guess that means I'm on the safe side. ;-)

Well, I have to say that I made a similar experience as DaveS: One timer fired several times although its Action event wasn't completed. Unfortunately, I found no comprehensive technical description and therefore had a hard time to figure out a solution.

The timer's action function MyTimerAction, which is part of a HTTPSocket object, was originally looking like this:

Me.ObjectCommunication.Value("Duration") = (Microseconds-Me.ObjectCommunication.Value("StartTime"))/1000
If Me.ObjectCommunication.Value("Duration").Int32Value > Me.ObjectCommunication.Value("Timeout") Then
Call GlobalFunctions.ProcessCheckResults(Me.ObjectCommunication.Value("Resource"),1,Me.ObjectCommunication.Value("Duration"))
MyTimer.Enabled = FALSE
Me.Close()
End If


The debugger claimed a stack overflow error somewhere at the global function (at different lines of code each time, which made it hard to track down the problem). The global function was called about fifty times before. Since it is only accessed by the timer, the timer has fired more than once for sure.

Interestingly, the debugger also showed up dozens of HTTPSocket objects at the time the stack overflow error occurred, although there should be just one object. Maybe the HTTPSocket object was kept alive because the passed values to the global function are held within a dictionary part of the HTTPSocket object. Anyway, it doesn't make much sense (variables should be taken over by value not by reference, shouldn't).

The trick that made it working as intended was to disable the timer first before calling the module (which executes a function that is quite time consuming, definitively more than 100 ms):

Me.ObjectCommunication.Value("Duration") = (Microseconds-Me.ObjectCommunication.Value("StartTime"))/1000
If Me.ObjectCommunication.Value("Duration").Int32Value > Me.ObjectCommunication.Value("Timeout") Then
MyTimer.Enabled = FALSE
Call GlobalFunctions.ProcessCheckResults(Me.ObjectCommunication.Value("Resource"),1,Me.ObjectCommunication.Value("Duration"))
Me.Close()
End If


Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 1:14 pm 
Offline

Joined: Fri Jan 06, 2006 3:21 pm
Posts: 12388
Location: Portland, OR USA
You can easily get into trouble with timers/reentrancy if you misuse DoEvents. But that would be a bug in your code.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 1:23 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
No DoEvents used. Definitively.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 1:51 pm 
Offline

Joined: Sat Jul 16, 2011 2:45 pm
Posts: 76
tobiaseichner wrote:
Interestingly, the debugger also showed up dozens of HTTPSocket objects at the time the stack overflow error occurred, although there should be just one object. Maybe the HTTPSocket object was kept alive because the passed values to the global function are held within a dictionary part of the HTTPSocket object. Anyway, it doesn't make much sense (variables should be taken over by value not by reference, shouldn't).
Real Studio uses reference counting, so if there is at least one object /property maintaining a reference to an object it will be kept alive - as soon as there is no longer a reference RealStudio's memory management will clean it up (when appropriate, so they might stay around for a little while).

Value types (Int, int32, unit32 etc) & primitive types (Strings, Arrays) are copied /overwritten directly. Everything else (Objects, classes etc) are reference types. An object that is kept within a property of a Socket that is passed to a property elsewhere shouldn't keep the socket alive, you would have to be storing a reference to the actual socket to keep it alive.. Any object that a socket was keeping references to, wont be removed so long as a references is still maintained elsewhere.

You shouldn't have a bunch of sockets unless you're creating and keeping those sockets - If you are finished with a socket you should close it too, rather than just drop it's references.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 2:47 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
> You shouldn't have a bunch of sockets unless you're creating and keeping those sockets - If you are finished with a socket you should close it too,
> rather than just drop it's references.

Yes, the sockets are closed, either by the function we talked about or somewhere else in code.

But even we consider the socket being not closed, why are there dozens of socket objects left open, even just a single one has been created before ? Unfortunately my code above is taken from a complex project I cannot post at this point, otherwise it would be probably easier for you to see what happens.

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 3:02 pm 
Offline

Joined: Sat Jul 16, 2011 2:45 pm
Posts: 76
I would assume that it's a problem in your code and therefore you are creating more sockets than you are expecting - I've done it more than once before, mistakes are easy to make.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 3:19 pm 
Offline

Joined: Wed Mar 22, 2006 11:15 am
Posts: 712
Location: Southern California
Thom McGrath wrote:
DaveS wrote:
Well I'll be.... I just tested it... and you are correct...

However.... I HAVE seen (and had to work around) situations where the timer fired every interval regardless..

And no threads were involved.

I'm sorry to sound harsh, but it's just not possible. Timers fire on the Main thread, and thread code is procedural. What you're suggesting is that code execution jumps forward and backward in the thread, which is an terrifying proposition.


It's been a while, but I recall having a problem due to timer reentry on Windows. To verify the issue at the time I created a simple test project that consisted of nothing but a 1000ms timer with this:
Break
Dim i As Integer
While True = True
i = i + 1
Wend


The break was so that I could see reentry in the debugger. Right now (2012r2.1) there is no reentry. You hit the break statement once and the loop keeps the timer from firing again. But a few years ago on Windows that was not the case. The timer would fire every 1000ms as if each Action event was being triggered by a new thread in the underlying RB framework.

To this day I have the work around code still sitting in the project where I ran into it. I did the same thing Dave suggested.

Again, it's not a problem now. But at some point in the past it was.

_________________
Daniel L. Taylor
Custom Controls for Real Studio WE!
Visit: http://www.webcustomcontrols.com/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group