RAD Studio VCL Reference
ContentsIndex
PreviousUpNext
TThread.Terminate Method

Signals the thread to terminate by setting the Terminated property to true.

Pascal
procedure Terminate;
C++
__fastcall Terminate();

Terminate sets the thread's Terminated property to true, signaling that the thread should be terminated as soon as possible.  

For Terminate to work, the thread's Execute method and any methods that Execute calls should check Terminated periodically and exit when it's true.

Note: Unlike the Windows API TerminateThread, which forces the thread to terminate immediately, the Terminate method merely requests that the thread terminate. This allows the thread to perform any cleanup before it shuts down.
 

C++ Examples: 

 

/*
The following example shows how to use the LockList and
UnlockList methods to access a thread-safe version  of a
TList object:
*/
class TMyThread : public TThread
{
__published:    // IDE-managed Components
private:    // User declarations
protected:  // User declarations
    void __fastcall Execute();
public:     // User declarations
    __fastcall TMyThread(bool suspended);
};

__fastcall TMyThread::TMyThread(bool suspended)
    : TThread(suspended)
{
}

class TYouThread : public TThread
{
__published:    // IDE-managed Components
private:    // User declarations
protected:  // User declarations
    void __fastcall Execute();
public:     // User declarations
    __fastcall TYouThread(bool suspended);
};

__fastcall TYouThread::TYouThread(bool suspended)
    : TThread(suspended)
{
}

class TListThread : public TThread
{
__published:    // IDE-managed Components
private:    // User declarations
protected:  // User declarations
    void __fastcall Execute();
public:     // User declarations
    __fastcall TListThread(bool suspended);
};

__fastcall TListThread::TListThread(bool suspended)
    : TThread(suspended)
{
}

TThreadList *threadList1;
bool mythreadRunning, youthreadRunning, listthreadRunning;
int globalCount;
TMyThread *secondProcess;
TYouThread *otherSecondProcess;
TListThread *listProcess; // thread arecustom descendants of TThread

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (mythreadRunning == FALSE)
  {
    mythreadRunning = TRUE;
    secondProcess = new TMyThread(True); // create suspended – secondprocess does not run yet
    secondProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
    secondProcess->Priority = tpLower;  // set the priority to lower than normal
    secondProcess->Resume(); // now run the thread
  }
  else
    MessageDlg("This thread is still running.  You are going to hurt yourself!",
      mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TMyThread::Execute()
{
  for (int I = 0; I <= 20; I++)
  {
    if (Terminated) break;
    TRadioButton *myRadio = new TRadioButton(Form1);
    globalCount = globalCount + 1;
    myRadio->Name = "RadioButton" + IntToStr(globalCount);
    threadList1->Add(myRadio);
    Sleep(1000);
  }
  mythreadRunning = FALSE;
}

void __fastcall TForm1::Button3Click(TObject *Sender)
{
  if (youthreadRunning == FALSE)
  {
    youthreadRunning = TRUE;
    otherSecondProcess = new TYouThread(True); // create suspended – other secondprocess does not run yet
    otherSecondProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
    otherSecondProcess->Priority = tpLower;  // set the priority to lower than normal
    otherSecondProcess->Resume(); // now run the thread
  }
  else
    MessageDlg("This thread is still running.  You are going to hurt yourself!",
      mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TYouThread::Execute()
{
  for (int I = 0; I <= 10; I++)
  {
    if (Terminated) break;
    try
    {
      TList *list = threadList1->LockList();
      if (2*I < list->Count)
      {
        TControl *Temp = (TControl *)list->Items[2*I];
        threadList1->Remove(Temp);
      }
    }
    __finally
    {
      threadList1->UnlockList();
    }
    if (Terminated)
      MessageDlg("youThread has been asked to terminate, but is still running!",
        mtInformation, TMsgDlgButtons() << mbOK, 0);
    Sleep(3000);
  }
  youthreadRunning = FALSE;
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if (listthreadRunning == FALSE)
  {
    listthreadRunning = TRUE;
    listProcess = new TListThread(True); // create suspended – secondprocess does not run yet
    listProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
    listProcess->Priority = tpLower;  // set the priority to lower than normal
    listProcess->Resume(); // now run the thread
  }
  else
    MessageDlg("This thread is still running.  You are going to hurt yourself!",
      mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TListThread::Execute()
{
  while(True)
  {
    if (Terminated) break;
    Form1->ListBox1->Clear();
    TList *myList = threadList1->LockList();
    try
    {
      for (int I = 0; I < myList->Count; I++)
      {
        TControl *Temp = (TControl *)myList->Items[I];
        Form1->ListBox1->Items->Add(Temp->Name);
      }
    }
    __finally
    {
      threadList1->UnlockList();
    }
    Sleep(1000);
  }
}

void __fastcall TForm1::Button4Click(TObject *Sender)
{
  if (listProcess != NULL)
    listProcess->Terminate();
  if (secondProcess != NULL)
    secondProcess->Terminate();
  if (otherSecondProcess != NULL)
    otherSecondProcess->Terminate();
}

 

Delphi Examples: 

{
The following example shows how to use the LockList and
UnlockList methods to access a thread-safe version  of a
TList object:
}
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button3: TButton;
    ListBox1: TListBox;
    Button2: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  TListThread = class(TThread)
  protected
    procedure Execute; override;
  end;
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;
  TYouThread = class(TThread)
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  threadList1: TThreadList;
  mythreadRunning, youthreadRunning, listThreadRunning: Boolean;
  globalCount: Integer;
  listProcess: TListThread; { TListThread is a custom descendant of TThread }
  secondProcess: TMyThread; { TMyThread is a custom descendant of TThread }
  otherSecondProcess: TYouThread; { TMyThread is a custom descendant of TThread }

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if (mythreadRunning = FALSE) then
  begin
    mythreadRunning:= TRUE;
    secondProcess := TMyThread.Create(True); { create suspended – secondprocess does not run yet }
    secondProcess.FreeOnTerminate := True; { don't need to cleanup after terminate }
    secondProcess.Priority := tpLower;  // set the priority to lower than normal
    secondProcess.Resume; { now run the thread }
  end
  else
    MessageDlg('This thread is still running.  You are going to hurt yourself!',
      mtInformation, [mbOk], 0);
end;

procedure TMyThread.Execute;
var
  I: Integer;
  myRadio: TRadioButton;
begin
  for I := 0 to 20 do
  begin
    if (Terminated) then
    begin
      mythreadRunning:= FALSE;
      exit;
    end;
    myRadio:= TRadioButton.Create(Form1);
    globalCount:= globalCount + 1;
    myRadio.Name:= 'RadioButton' + IntToStr(globalCount);
    threadList1.Add(myRadio);
    Sleep(1000);
  end;
  mythreadRunning:= FALSE;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if (listthreadRunning = FALSE) then
  begin
    listThreadRunning:= TRUE;
    listProcess := TListThread.Create(True); { create suspended – secondprocess does not run yet }
    listProcess.FreeOnTerminate := True; { don't need to cleanup after terminate }
    listProcess.Priority := tpLower;  // set the priority to lower than normal
    listProcess.Resume; { now run the thread }
  end;
end;

procedure TListThread.Execute;
var
  I: Integer;
  Temp: TControl;
  myList: TList;
begin
  while(True) do
  begin
    if (Terminated) then
    begin
      listthreadRunning:= FALSE;
      exit;
    end;
    Form1.ListBox1.Clear;
    myList:= threadList1.LockList;
    try
      for I := 0 to myList.Count-1 do
      begin
        Temp:= myList.Items[I];
        Form1.ListBox1.Items.Add(Temp.Name);
      end;
    finally
      threadList1.UnlockList;
    end;
    Sleep(1000);
  end;
  listthreadRunning:= FALSE;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  if (youthreadRunning = FALSE) then
  begin
    youthreadRunning:= TRUE;
    otherSecondProcess := TYouThread.Create(True); { create suspended – secondprocess does not run yet }
    otherSecondProcess.FreeOnTerminate := True; { don't need to cleanup after terminate }
    otherSecondProcess.Priority := tpLower;  // set the priority to lower than normal
    otherSecondProcess.Resume; { now run the thread }
  end
  else
    MessageDlg('This thread is still running.  You are going to hurt yourself!',
      mtInformation, [mbOk], 0);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  if (listProcess <> nil) then
    listProcess.Terminate;
  if (secondProcess <> nil) then
    secondProcess.Terminate;
  if (otherSecondProcess <> nil) then
    otherSecondProcess.Terminate;
end;

procedure TYouThread.Execute;
var
  I: Integer;
  Temp: TControl;
begin
  for I := 0 to 10 do
  begin
    if (Terminated) then
    begin
      youThreadRunning:= FALSE;
      exit;
    end;
    with threadList1.LockList do
    try
      if (2*I < Count) then
      begin
        Temp:= Items[2*I];
        threadList1.Remove(Temp);
      end;
    finally
      threadList1.UnlockList;
    end;
    if (Terminated) then
      MessageDlg('youThread has been asked to terminate, but is still running!',
        mtInformation, [mbOk], 0);
    Sleep(3000);
  end;
  youthreadRunning:= FALSE;
end;

 

Copyright(C) 2008 CodeGear(TM). All Rights Reserved.
What do you think about this topic? Send feedback!