TThread sleep and terminate. - Delphi
This is a discussion on TThread sleep and terminate. - Delphi ; Say I have a background thread that Sleeps for 1 second, like this..
procedure TMyThread.Execute();
begin
while (not Terminated) do
begin
// do somthing interesting!
windows.sleep(1000);
end;
end;
If i call terminate i still have to wait for the thread ...
-
TThread sleep and terminate.
Say I have a background thread that Sleeps for 1 second, like this..
procedure TMyThread.Execute();
begin
while (not Terminated) do
begin
// do somthing interesting!
windows.sleep(1000);
end;
end;
If i call terminate i still have to wait for the thread to be woken up by
windows? So is there a way to get the thread to terminate quickly, or do i
always have to wait for it to finish sleeping? I only need it to wake up
every second or so, but i dont a second or so delay when i come to terminate
the thread.
thanks.
-
Re: TThread sleep and terminate.
Fubar wrote:
> Say I have a background thread that Sleeps for 1 second, like this..
>
> procedure TMyThread.Execute();
> begin
> while (not Terminated) do
> begin
> // do somthing interesting!
> windows.sleep(1000);
> end;
> end;
>
> If i call terminate i still have to wait for the thread to be woken up by
> windows?
Of course. Look at the very simple implementation of TThread.Terminate.
> So is there a way to get the thread to terminate quickly, or do i
> always have to wait for it to finish sleeping? I only need it to wake up
> every second or so, but i dont a second or so delay when i come to terminate
> the thread.
Create an event (such as with CreateEvent). Give your thread class a new
Terminate method, and in that method call SetEvent to put the event into
the signaled state.
In your Execute method, use WaitForSingleObject like this:
while WaitForSingleObject(FEvent, 1000) = Wait_TimeOut do begin
// do something interesting
end;
That will make your thread wait for up to one second for the event to be
signaled. If it's not signaled in that time, then the function times
out, and you go through the loop body once. If it doesn't time out, then
the return value will be either Wait_Object_0 -- to indicate that the
event is signaled -- or Wait_Failed -- to indicate that something went
wrong. Either case may be grounds for terminating the thread.
Instead of CreateEvent and SetEvent, you could use a TSimpleEvent from
the SyncObjs unit. Even better if its WaitFor method can time out.
(Otherwise, pass its Handle value to WaitForSingleObject.)
--
Rob
-
Re: TThread sleep and terminate.
"Fubar" <fu@bar.com> wrote in message
news:475df57e$1@newsgroups.borland.com...
> If i call terminate i still have to wait for the thread to
> be woken up by windows?
Yes. TThread.Terminate() merely sets the TThread. Terminated property to
True and does nothing else. It is Execute()'s responsibility to check the
value of the Terminated property periodically.
> So is there a way to get the thread to terminate quickly
Use a kernel event object, either via the VCL TEvent class or the
Windows.CreateEvent() function directly. Instead of using Windows.Sleep(),
you can use TEvent.WaitFor() or WaitForSingleObject(), specifying a timeout.
Then use TEvent.SetEvent() or Windows.SetEvent() instead of, or in addition
to, TThread.Terminate(). For example:
type
TMyThread = class(TThread)
private
FTerminateEvent: TEvent;
protected
procedure Execute; override
public
constructor Create(ACreateSuspended: Boolean); override;
destructor Destroy; override;
procedure Stop;
end;
constructor TMyThread.Create(ACreateSuspended: Boolean);
begin
FTerminateEvent := TEvent.Create(nil, True, False, '');
inherited;
end;
destructor TMyThread.Destroy;
begin
FTerminateEvent.Free;
inherited;
end;
procedure TMyThread.Stop;
begin
Terminate;
FTerminateEvent.SetEvent;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
// do somthing interesting!
FTerminateEvent.WaitFor(1000);
end;
end;
> do i always have to wait for it to finish sleeping?
If you continue to use Sleep(), then yes.
Gambit