TThreadList (C++)

From RAD Studio Code Examples
Jump to: navigation, search

Description

The following example shows how to use the LockList and UnlockList methods to access a thread-safe version of a TList object:


Code

#include <memory> // For the auto_str

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; //Threads are custom descendants of TThread.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (mythreadRunning == FALSE)
  {
	mythreadRunning = TRUE;
	secondProcess = new TMyThread(True); // Creation is suspended--second process does not run yet.
	secondProcess->FreeOnTerminate = True; // Do not need to clean up after termination.
	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); // The owner (Form1) will clean this up.
	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); // Creation is suspended-- the other second process does not run yet.
	otherSecondProcess->FreeOnTerminate = True; // No need to clean up after termination
	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 = reinterpret_cast<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); // Creation suspended -- the second process does not run yet.
	listProcess->FreeOnTerminate = True; // No need to clean up after termination
	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 = reinterpret_cast<TControl *>(myList->Items[I]);
		Form1->ListBox1->Items->Add(Temp->Name);
	  }
	}
	__finally
	{
	  threadList1->UnlockList();
	}
    Sleep(1000);
  }
}

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

__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
  mythreadRunning = FALSE;
  youthreadRunning = FALSE;
  listthreadRunning = FALSE;
  listProcess = NULL;
  secondProcess = NULL;
  otherSecondProcess = NULL;
  static std::auto_ptr<TThreadList> _threadList1Cleaner(threadList1 = new TThreadList());
  for (int I = 1; I <= 5; I++)
  {
	TRadioButton *RadioButton = new TRadioButton(Form1); // The owner (Form1) will clean this up.
	RadioButton->Name = "RadioButton" + IntToStr(I);
	threadList1->Add(RadioButton);
  }
  globalCount = 5;
}

Uses