Various answers suggest it is a bad idea to sleep inside a thread, for example: Avoid sleep. Why exactly? One reason often given is that it is difficult to gracefully exit the thread (by signalling it to terminate) if it is sleeping.
Let's say I wanted to periodically check for new files in a network folder, maybe once every 10s. This seems perfect for a thread with the priority set to low (or lowest) because I don't want the potentially time-consuming file I/O to impact my main thread.
What are the alternatives? Code is given in Delphi but would apply equally to any multi-threaded application:
procedure TNetFilesThrd.Execute();
begin
try
while (not Terminated) do
begin
// Check for new files
// ...
// Rest a little before spinning around again
if (not Terminated) then
Sleep(TenSeconds);
end;
finally
// Terminated (or exception) so free all resources...
end;
end;
A minor modification might be:
// Rest a little before spinning around again
nSleepCounter := 0;
while (not Terminated) and (nSleepCounter < 500) do
begin
Sleep(TwentyMilliseconds);
Inc(nSleepCounter);
end;
but this still involves a Sleep...
The standard way to do this is to wait on a cancellation event. In pseudo code that looks like this:
while not Terminated do
begin
// Check for new files
// ...
// Rest a little before spinning around again
FTerminationEvent.WaitFor(TenSeconds);
end;
In order to terminate you would override TerminatedSet
:
procedure TMyThread.TerminatedSet;
begin
inherited;
FTerminationEvent.SetEvent; // abandon the wait in the thread method
end;
The wait on the event either times out, or terminates because the event is signaled. This allows your thread to pause for a while and not burden the CPU, and yet also remain responsive to requests to terminate.
If this was my job, I think I would have solved it with a wrapper class with a TTimer in it, spawning a new thread every 10 seconds.
Spawning a new thread is somewhat costly, but if it's something that you do only every 10 seconds, the performance hit to the main thread is negligible, I think.
Steps:
There'd be some other considerations too, such as keeping track of whether or not a thread has been spawned, so that you do not create an new thread while the old one is running.
But, other than this, I think it should be pretty straight forward to implement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With