unit EnumeratorThread;

interface

uses
  Classes, SysUtils, Controls, StdCtrls, Windows;

type
  TEnumeratorThread = class(TThread)
  private
    FCurrNbr : Integer;
    FStop    : Integer;
    FMemo    : TMemo;

  protected
    procedure Execute; override;
    procedure AddNewNumberToMemo;

  public
    constructor Create(const Memo : TMemo);
    procedure GentleStop;
  end;

implementation

{ TEnumeratorThread }

// BeginExample: ThreadSynchronize
// Method: Classes.TThread.Synchronize
// Method: Classes.TThread.WaitFor

// BeginCode
{
This example demonstrates the use of Synchronize method to execute a procedure
on the main thread that "owns" the GUI. Also WaitFor is used to wait for the
thread's termination.
}
procedure TEnumeratorThread.AddNewNumberToMemo;
begin
  { Increase current number and add it to the memo }
  Inc(FCurrNbr);
  FMemo.Lines.Add(IntToStr(FCurrNbr));
end;

constructor TEnumeratorThread.Create(const Memo: TMemo);
begin
  { Initialize internal fields }
  FMemo := Memo;
  FCurrNbr := 0;
  FStop := 0;

  inherited Create(true);
end;

procedure TEnumeratorThread.Execute;
begin
  { Repeat the loop until the flag says otherwise }
  while FStop = 0 do
  begin
    { Wait for 100 milli }
    Sleep(100);

    {
    Run AddNewNumberToMemo procedure on the main thread - makes
    it safe to access GUI from this thread.
    }
    Synchronize(AddNewNumberToMemo);
  end;

  FStop := 0;
end;

procedure TEnumeratorThread.GentleStop;
begin
  { Set the flag to 1 }
  InterlockedIncrement(FStop);

  { Wait for this thread to finish executing }
  Self.WaitFor;
end;

// EndCode
// EndExample: ThreadSynchronize

end.
