Use a TEvent
object instead of Sleep()
, eg:
type
TMyThreadTimer = class(TThread)
private
FTermEvent: TEvent;
procedure _smartSleep(Timeout: Integer);
protected
procedure Execute; override;
procedure TerminatedSet; override; // XE2+ only *
public
constructor Create(ACreateSuspended: Boolean); override;
destructor Destroy; override;
end;
constructor TMyThreadTimer.Create(ACreateSuspended: Boolean);
begin
inherited Create(ACreateSuspended);
FTermEvent := TEvent.Create(nil, True, False, '');
end;
destructor TMyThreadTimer.Destroy;
begin
//inherited calls TerminatedSet where FTermEvent should not be freed yet
inherited;
FTermEvent.Free;
end;
procedure TMyThreadTimer.Execute;
begin
...
end;
procedure TMyThreadTimer.TerminatedSet;
begin
FTermEvent.SetEvent;
end;
procedure TMyThreadTimer._smartSleep(Timeout: Integer);
begin
FTermEvent.WaitFor(Timeout);
end;
This way, while the thread is running normally, _smartSleep()
will sleep more efficiently, and as soon as you Terminate()
the thread (as Terminate()
calls TerminatedSet()
), any sleep that is in progress will stop immediately.
* If you are using a Delphi version prior to XE2, you will have to implement your own method to signal the TEvent
when needed. For example, adding a public Stop()
method to the thread class and have it call Terminate()
and FTermEvent.SetEvent()
, then call that method instead of calling Terminate()
directly.