Ron Sommer Guest
|
Posted: Wed Nov 05, 2003 9:52 am Post subject: Smooth blinking |
|
|
Hi !
Currently, I'm using a high priority threaded timer to make sure that
events do not occur some time after a given interval ends, but around
the time they should occur at. Example: If I set an interval of 3000 ms,
and the system is very busy, the event might occur after, lets say, 4500
ms. I therefore use WaitForSingleObject to check, if more than 2900 ms
have passed, every 100 ms, therefore firing the event up at the desired
+/- 100 ms.
Though this works perfectly, as it seems, for very short intervals, the
actual wait time may differ strongly from the interval requested. If,
for example, I want an event to occur every 300 ms, the actual time
between two evens might vary between 201 and 400 ms (= by 100%).
This wouldn't happen, if the WaitForSingleObject call would start
exactly at the time it should, I guess, so the problem is the variation
of the first interval period - or am I wrong ?? I have attached the
important part of the source.
The result is, that the control blinks steadily after the first
interval, but not at first: When the timer is started, the control
vanishes too early, as if it was in a hurry. All subsequent calls to
Control->Visible = ... occur on time, however.
Do you have an idea on how to improve this behaviour ? (Except for
setting the WaitForSingleObject timeout to a minimum, which doesn't seem
to help.)
Regards,
Ron Sommer
....
BlinkTimer = new TThreadedTimer(this);
BlinkTimer->Interval = 300;
BlinkTimer->OnTimer = DoBlink;
BlinkTimer->Enabled = false;
....
void __fastcall TTimerThread::Execute()
{
unsigned long Ticks, LastTicks = 0;
do {
if (WaitForSingleObject(FStop, 100) == WAIT_TIMEOUT && FEnabled) {
Ticks = GetTickCount() / FInterval;
if (Ticks > LastTicks) {
LastTicks = Ticks;
Synchronize(FOwner->Sync);
}
}
} while (!Terminated);
}
__fastcall TThreadedTimer::TThreadedTimer(TComponent *AOwner):
TComponent(AOwner)
{
FTimerThread = new TTimerThread(true);
FTimerThread->FOwner = this;
FTimerThread->FInterval = 1000;
FTimerThread->Priority = tpNormal;
// Event is completely manipulated by TThreadedTimer object
FTimerThread->FStop = CreateEvent(NULL, false, false, NULL);
}
void __fastcall TThreadedTimer::SetEnabled(bool Value)
{
....
if (FEnabled) ...
SetEvent(FTimerThread->FStop);
FTimerThread->FEnabled = true;
FTimerThread->Resume();
....
}
....
|
|