4

How can I Pause/Continue TThread I am looking for a safe alternative to the deprecated TThread.Suspend aswell as TThread.Resume.

Mike Torrettinni
  • 1,816
  • 2
  • 17
  • 47

1 Answers1

5

Here is the solution I ended up with. Safe alternative to Suspend/Resume.

     type
      TMyThread = class(TThread)
      private
        FHandles: array[0..1] of THandle;
      protected
        procedure Execute; override;
      public
        constructor Create;
        destructor Destroy; override;
        procedure Pause;
        procedure UnPause;
        procedure Stop;
      end;

      constructor TMyThread.Create;
      begin
        inherited Create(False);
        FHandles[0] := CreateEvent(nil, False, False, nil);
        FHandles[1] := CreateEvent(nil, True, True, nil);
        FreeOnTerminate := True;
      end;

      destructor TMyThread.Destroy;
      begin
        CloseHandle(FHandles[1]);
        CloseHandle(FHandles[0]);
        inherited Destroy;
      end;

      procedure TMyThread.Execute;
      begin
        while not Terminated do
        begin
          case WaitForMultipleObjects(2, @FHandles[0], False, INFINITE) of
            WAIT_FAILED:
              RaiseLastOsError;
            WAIT_OBJECT_0:
              Terminate;
            WAIT_OBJECT_0 + 1:
              begin

              end;
          end;
        end;

      end;

      procedure TMyThread.Pause;
      begin
        ResetEvent(FHandles[1]);
      end;

      procedure TMyThread.UnPause;
      begin
        SetEvent(FHandles[1]);
      end;

      procedure TMyThread.Stop;
      begin
        SetEvent(FHandles[0]);
      end;
  • I'm having something similar in my threads (because I'm targeting only Windows platform and do not like the `TEvent` class). One thing I would improve in this code. In the `Stop` method I would write just `Terminate` and the exit event I would signal in the `TerminatedSet` method. That allows to *gracefully* exit your thread when the application terminates (without the need to calling `Stop`). In the `Execute` method you can then just `Exit` when this event is signalled. It is also good to identify the events somehow. Maybe [`like this`](http://pastebin.com/8JdA4prE). – TLama Aug 15 '14 at 12:28
  • 1
    @TLama This is even better! Thanks! :) – Daniel Bauer Aug 15 '14 at 12:31
  • 2
    @TLama: thanks for the `TerminatedSet()` hint, I never knew about that one. Looks like it was introduced in/near XE2. – Remy Lebeau Aug 15 '14 at 15:38