A Better Timer for a Delphi Programmer

The standard VCL TTimer component is a wrapper for the Windows API timer functions SetTimer and KillTimer. TTimer simplifies the processing of the WM_TIMER messages by converting them into OnTimer events. A timer based on WM_TIMER message processing cannot provide a resolution better than 10 milliseconds. And even when the timer interval is set to tens of milliseconds, the actual timer intervals are noticeably higher. The Windows API provides several opportunities to make a better timer – these are multimedia timers, waitable timers and queue timers. I have tried the third alternative (queue timer) as a replacement for the standard VCL TTimer component. The result is TksTimer component added to the ksTools package version 0.46. From the end user point of view the main difference between TTimer and TksTimer is a setting of the timer interval. TksTimer encapsulates the additional functionality of the queue timers and uses 2 properties (namely DueTime and Period) to set the timer interval. The DueTime property sets the interval between the moment the timer is enabled and the moment the timer fires for the first time. The Period property sets the interval between the subsequent timer events. If the Period is set to zero, the timer fires only once.
I have also written TimerTests application to compare the efficiency of TTimer and TksTimer. The difference is outstanding for the intervals of 100 milliseconds or less. I have obtained the following correlation between the set intervals and the average actual timer intervals (in milliseconds) on my computer (Pentium IV, 3.2 GHz, 2Gb RAM, Win XP):

Interval   TTimer  TksTimer
----------------------------
  100        108       100
   50         62        50
   20         31        20
   10         15        11
    5         15         6
    2         15         3
    1         14         2

9 thoughts on “A Better Timer for a Delphi Programmer

  1. If you change TTimer.Interval while TTimer is running the timer is stopped and restarted internally. It is easy to implement the same functionality for TksTimer, but I have not done it. Probably because TksTimer has two properties (DueTime and Period) instead of single TTimer.Interval.

    So you should explicitly stop and restart TksTimer to change interval value:

      Timer.Enabled:= False;
      Timer.DueTime:= ..;
      Timer.Period:= ..;
      Timer.Enabled:= True;
    
    • i have an while loop i will to slow his work to view there output step by step using a timer how i can do ?

  2. Serg
    It works good with Delphi 4 as long as I comment out Classes.

    FWindowHandle:= {Classes.}AllocateHWnd(WndProc)
    {Classes.}DeallocateHWnd(FWindowHandle);
    AL

  3. Hi. I’ve starting using ksTimer.pas and have been impressed with the accuracy with high frequencies. However, I have needed to fix a couple of issues in the code. The first is in procedure TksTimer.Timer. I added a check for FEnabled since I found that it was possible for the callback to be triggered even after the timer has been disabled. This is dangerous since you may have already freed objects used by the timer event and cause an access violation. The second is in procedure TksTimer.SetPeriod as it was not possible to change the period while the timer was enabled. In this case it will disable the timer, then set the period and re-enable. Finally, I set the default FDueTime to 0 in the constructor since I think it’s the most commonly used value. I got caught out the first time wondering why it took 1s to start the timer (TTimer doesn’t have this feature). Contact me if you’d like the modified code.

Leave a comment