當TThread
後代的工作我基本上有一個選擇:終止線程變量,並將其設置爲NULL
- 設置
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之前是否執行了執行。我可以重新啓動線程而不終止它(我不需要在程序結束之前刪除對象) - 如果我啓動線程,我會得到「無法在運行或掛起的線程上調用啓動」異常。
我確實嘗試過,但是您確定可以將MyThread設置爲ThreadTerminated事件內部的NULL嗎?如果對象尚未釋放,是否會導致訪問衝突? – Coder12345 2013-04-04 20:44:37
@ Coder12345:是的,我確定。 'OnTerminate'事件是通過'Synchronize()'觸發的,直到'OnTerminate'事件處理程序退出之後,線程對象纔會被釋放。 – 2013-04-04 20:46:45
謝謝雷米,很好的答案,一切都很好。 – Coder12345 2013-04-04 21:27:59