TThreadList (C++)
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
- System.Classes.TThreadList.LockList ( fr | de | ja )
- System.Classes.TThreadList.UnlockList ( fr | de | ja )
- System.Classes.TThreadList.Add ( fr | de | ja )
- System.Classes.TThreadList.Remove ( fr | de | ja )
- System.Classes.TThread.Terminate ( fr | de | ja )
- System.Classes.TThread.Terminated ( fr | de | ja )