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 ...

+ Reply to Thread
Results 1 to 3 of 3

TThread sleep and terminate.

  1. Default 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.



  2. Default 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

  3. Default 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



+ Reply to Thread