Recent

Author Topic: exact starting of a timer  (Read 4630 times)

frederic

  • Full Member
  • ***
  • Posts: 226
exact starting of a timer
« on: March 09, 2017, 09:49:59 am »
dear specialist.

I wondered if there is a simple  routine to start a number of procedures exact at the start of a new minute in the day.

Up till now i used folowwing
Code: Pascal  [Select][+][-]
  1. procedure TForm1.realTimer1Timer(Sender: TObject);
  2. begin
  3.   Fcurrentfocusminute:= trunc(1440*( now-   Fdubstarttime ));
  4.     if FlastRTfocusminuut <>Fcurrentfocusminute  then
  5.     begin
  6.       // filling the minute arrays
  7.        ...........
  8.       // filling  a new stringgrid row
  9.        ........
  10.       FlastRTfocusminuut := Fcurrentfocusminute;
  11.     end;
  12. end;          


or i used an editbox were  the minute of the day is presented .with the editchange an new procedure can be started

frederic

jmm72

  • Jr. Member
  • **
  • Posts: 79
  • Very experienced in being a beginner...
Re: exact starting of a timer
« Reply #1 on: March 14, 2017, 12:55:11 pm »
One of the problems you will have with using timers is that the timers are guaranteed to run for a minimum timer, but there's no maximum. So between timer triggers, if you do something that takes longer than the timer, then the timer will not be triggered until that task finishes. Even if you place carefully Application.ProcessMessages along the procedures so the timer triggers when you want, you might end having multiple unfinished procedure calls when you push the timer code.

All this is to tell you that you should be sure that your timer code is not being executed multiple times simultaneously.
Also look at creating timers at run-time, or changing the timer lapse so it triggers at the next minute change, something like Timer1.Interval := (number of milliseconds from Now() to next minute)
Lazarus 1.6.4 + FPC 3.0.2 64bits under Windows 7 64bits
Only as a hobby nowadays
Current proyect release: TBA

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: exact starting of a timer
« Reply #2 on: March 14, 2017, 04:28:29 pm »
Also look at creating timers at run-time, or changing the timer lapse so it triggers at the next minute change, something like Timer1.Interval := (number of milliseconds from Now() to next minute)
I kept from replying to thread because what he is doing with the code above is more accurate timing (in long term) for "do something every minute" than if setting interval to 60000.

cpicanco

  • Hero Member
  • *****
  • Posts: 618
  • Behavioral Scientist and Programmer
    • Portfolio
Re: exact starting of a timer
« Reply #3 on: March 15, 2017, 05:38:06 pm »
If you do need to run stuff in parallel, I have writen a custom timer that uses a thread to execute OnTimer events.

https://github.com/cpicanco/stimulus_control/blob/master/units/custom_timer.pas
Be mindful and excellent with each other.
https://github.com/cpicanco/

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: exact starting of a timer
« Reply #4 on: March 17, 2017, 02:33:47 am »
If you do need to run stuff in parallel, I have writen a custom timer that uses a thread to execute OnTimer events.

https://github.com/cpicanco/stimulus_control/blob/master/units/custom_timer.pas
Good idea but, using synchronize or any other way to inform the main thread that code needs to be executed has the same problem that the timer has you need to execute the timer event in the thread to avoid long running processes problems.

jmm72

  • Jr. Member
  • **
  • Posts: 79
  • Very experienced in being a beginner...
Re: exact starting of a timer
« Reply #5 on: March 17, 2017, 03:43:05 pm »
I went into something similar recently, calling the same function from a timer when the previous one didn't finish. It caused an endless loop. I'd rather not say how long it took me to debug it, mainly because I thought it was in a completely different unit and task, until I discovered the loop running in a totally accidental way.

In short: always be sure that routines called from events are not running already. If it's from a button, then disable the button as soon as the onclick event procedure starts. If it's from a timer or similar, use some kind of global flag and don't call the routine it if the flag is enabled (and disable the flag when the function finishes). Exact implementation up to your tastes.

Sometimes it's harmless, other times it's not but you spot the problem quickly. But when you don't see it, specially with timers... Mayhem.

About checking the second every second, it might be as exact as just putting a timer on 60000. After all, the check is based on a timer, which is not guaranteed to be exact, p.e. if there's another function doing something long between calls to ProcessMessages. The timer on another thread might call the synchronize on an exact time, but IIRC that puts the call to the routine on the message queue, isn't it? so same problem. It would be good only if the code to be executed is in the timer thread.
Lazarus 1.6.4 + FPC 3.0.2 64bits under Windows 7 64bits
Only as a hobby nowadays
Current proyect release: TBA

cpicanco

  • Hero Member
  • *****
  • Posts: 618
  • Behavioral Scientist and Programmer
    • Portfolio
Re: exact starting of a timer
« Reply #6 on: March 17, 2017, 05:43:46 pm »
I went into something similar recently, calling the same function from a timer when the previous one didn't finish.

Would asynchronous calls solve your problem?: http://wiki.freepascal.org/Asynchronous_Calls It is really a question, not a recommendation.

Also, for threads, would critical sections solve your problem? http://www.freepascal.org/docs-html/prog/progse45.html
« Last Edit: March 17, 2017, 05:59:17 pm by cpicanco »
Be mindful and excellent with each other.
https://github.com/cpicanco/

 

TinyPortal © 2005-2018