Timers in .Net

The scrolling marquee component in the Essentials suite made use of multimedia timers (timeSetEvent) to control the speed at which the text scrolled across the label. While a multimedia time has a finer resolution and is more accurate than a standard Windows timer, the multimedia timer caused problems in the form of sporadic uninitialized pointer errors. Since I was unable to track down the exact cause of the problem and since I didn’t need the additional accuracy provided by the multimedia timer, I switched to one of the standard timers provided by the .Net framework. Namely, System.Threading.Timer.

Using System.Threading.Timer is quite easy. You merely have to create a callback function that get called when the timer fires, create a Timer object and use the Change method to activate / deactivate the timer and to change the interval at which it fires.

The Callback Methods

Since the callback methods is called in the context of a thread other than the main thread, it was necessary to queue a message to the main thread to let it know that the event had fired. This is quite similar to the way that timeSetEvent works so minimal changes to the existing callback function were required. I just made it member of the TEsCustomScrollingMarquee component and changed the parameter list to that required by the Timer component.

procedure TEsCustomScrollingMarquee.smTimerProc(Sender: TObject);
begin
PostMessage(smHandle, SM_TIMER, 0, 0);
end;

Creating the Timer

Rather than creating and destroying the Timer each time it was activated or deactivated I created the Timer in the marquee component’s constructor and release the Timer’s resources in the marquee component’s destructor.

// Create a timer
smTimer := Timer.Create(smTimerProc);
// Free resources held by the timer
if (Assigned(smTimer)) then
smTimer.Dispose;

Activating the Timer

The timer is activated using the Change method. Setting the dueTime and period parameters to values other than Timeout.Infinite start the timer running. Setting dueTime and period parameters to Timeout.Infinite stops the timer.

Leave a Reply