子孫を扱うとき、TThread
私は基本的に選択肢があります:
- 子孫オブジェクトを削除しますが、設定
FreeOnTerminate
しませんtrue
TThread
NULL
- 手動で行い、自分で削除するという混乱をすべて経験します
基本的に必要なのは、スレッドが実行されているかどうかを判断する方法なので、次のことを行いました。
//------------------------------------------------------------------------------
// Thread descendant
//------------------------------------------------------------------------------
class TMyThread : public TThread
{
private: UnicodeString StatusLine; // Used for Synchronize function
void __fastcall UpdateGUI();
protected: virtual void __fastcall Execute();
public: __fastcall TMyThread();
};
//------------------------------------------------------------------------------
TMyThread *MyThread;
//------------------------------------------------------------------------------
// Thread constructor
__fastcall TMyThread::TMyThread() : TThread(true)
{
FreeOnTerminate = false;
Priority = tpNormal;
}
// Synchronize function for Form1
void __fastcall TMyThread::UpdateGUI()
{
Form1->Label1 = StatusLine;
}
// Execute code
void __fastcall TMyThread::Execute()
{
Sleep(2000);
StatusLine = "I am almost done!";
Synchronize(&UpdateGUI);
}
// Thread terminate, delete object, set to NULL
void __fastcall TForm1::ThreadTerminateIfDone(TMyThread *T)
{
if (T != NULL && WaitForSingleObject(reinterpret_cast<void*>(T->Handle),0) == WAIT_OBJECT_0)
{
T->Terminate();
T->WaitFor();
delete T;
T = NULL;
}
}
// And initialization part which needs to check if thread is already running
void __fastcall TForm1::StartOrRestartThread(TObject *Sender)
{
// Remove old thread if done
ThreadTerminateIfDone(MyThread);
// Check if thread is running - NULL = not running and terminated or uninitialized
if (MyThread == NULL)
{
MyThread = new TMyThread();
MyThread->Start();
}
else
{
Application->MessageBox(L"Thread is still running please wait!", L"Error", MB_OK);
}
}
このコードはそのまま動作します。私の質問は次のとおりです。
これを簡単にする方法はありますか?
MyThread
開始/再起動の次の呼び出しまでオブジェクトが存在しないように、完了後に NULLに設定する必要がありますか?FreeOnTerminate
オブジェクトを削除するため、これを trueに設定すると実行できません。オブジェクトにアクセスしようとすると、例外が生成されます(キャッチできますが、それはばかげています)。MyThread を初期化または再起動する前に、実行が完了しているかどうかを知る必要があるだけです。スレッドを終了せずに再起動できますか (プログラムが終了するまでオブジェクトを削除する必要はありません)。