Search code examples
multithreadingdelphibitmapdelphi-xe7

How to pause a thread?


I want to draw something. Because the GUI freezes I want to draw in a thread. But sometimes I want to pause the drawing (for minutes).

Delphi's documentation says that Suspend/resume are obsolete but doesn't tell which functions replaces them.

Suspend and Resume are deprecated. Sleep and SpinWait are obviously inappropriate. I am amazed to see that Delphi does not offer such a basic property/feature.

So, how do I pause/resume a thread?


Solution

  • You may need fPaused/fEvent protection via a critical section. It depends on your concrete implementation.

    interface
    
    uses
      Classes, SyncObjs;
    
    type
      TMyThread = class(TThread)
      private
        fEvent: TEvent;
        fPaused: Boolean;
        procedure SetPaused(const Value: Boolean);
      protected
        procedure Execute; override;
      public
        constructor Create(const aPaused: Boolean = false);
        destructor Destroy; override;
    
        property Paused: Boolean read fPaused write SetPaused;
      end;
    
    implementation
    
    constructor TMyThread.Create(const aPaused: Boolean = false);
    begin
      fPaused := aPaused;
      fEvent := TEvent.Create(nil, true, not fPaused, '');
      inherited Create(false);
    end;
    
    destructor TMyThread.Destroy;
    begin
      Terminate;
      fEvent.SetEvent;
      WaitFor;
      fEvent.Free;
      inherited;
    end;
    
    procedure TMyThread.Execute;
    begin
      while not Terminated do
      begin
        fEvent.WaitFor(INFINITE);
        // todo: your drawings here
      end;
    end;
    
    procedure TMyThread.SetPaused(const Value: Boolean);
    begin
      if (not Terminated) and (fPaused <> Value) then
      begin
        fPaused := Value;
        if fPaused then
          fEvent.ResetEvent else
          fEvent.SetEvent;
      end;
    end;