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