Disable Delphi TTimer during the OnTimer event by Scott Hollows

emailx45

Местный
Регистрация
5 Май 2008
Сообщения
3,571
Реакции
2,438
Credits
573
Disable Delphi TTimer during the OnTimer event
Scott Hollows - 17/Dec/2017
[SHOWTOGROUPS=4,20]
When writing a Delphi TTimer event, I often disable the timer and re-enable it at the end of the event.

If you dont do this, the OnTimer event could fire again before you have finished processing it.
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.enabled := FALSE;  // disable the timer so it wont fire while we are processing it
      // oh oh - user interaction.
      // The timer can fire again while the message is displayed
      // if it is not disabled
  Try
    ShowMessage ('Hello'); 
  finally
    Timer1.enabled := TRUE;  // restore the timer
 end;
end;

If you dont do that the ShowMessage window would appear multiple times like in this example
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
  // timer event displaying a message
begin
  Memo1.lines.add ('OnCreate'); // debug message to show the timer is firing
  ShowMessage ('Hello'); 
end;

delphi_timer_animated


The timer re-firing before the earlier timer event has completed will only occurs in a few scenarios such as:

1) when the OnTimer code is waiting on user input such as when displaying a message
2) when the OnTimer calls Application.ProcessMessages
3) I havent tested this when using threaded code, but it might occur there as well
4) There are probably other scenarios. Post a comment if you know of any

It does not occur when the timer is calling the sleep function or when it is simply executing a long running chunk of code without any user interaction – such as calling this rather boring but slow procedure
Код:
procedure SlowProcedure;
 // do something really slow
// this takes 3 to 10 seconds on a 2017 PC
var
i : integer;
x : integer;
begin
for i := 1 to 500000000 do
x := trunc(x / i);
end;

Downsides
Using this technique can result in “Timer Creep” where the timer fires slower than the duration that you defined in the Interval property.

That is due to the timer countdown being reset when you re-enable it at the end of the event.

For example, if you have a 1000 millisecond timer interval and your OnCreate event takes 200 milliseconds to run. The timer will fire every 1200 milliseconds instead of the 1000 that you were expecting. If that is an issue for you, you could use a lower Interval value or capture the start and finish time in the OnTimer event and adjust the interval based on the original interval adjusted for the time difference.

Error Handling
Using Try / Finally is important in this technique. If an untrapped error occurs the timer will never fire again – Eeep !

Author – Thanks to the nudge from Linden R about the importance of Try / Finally in this technique


[/SHOWTOGROUPS]