Question and Answer Database FAQ2373C.txt TThread Run () in OWL Category :OWL Platform :All Product :C++Builder 3.x Question: How to use Run () in a TThread in OWL? Answer: There is a missing function in the docs: virtual int Run(); Basically, it goes like this: a) You derive from TThread and override Run(). Any code executing from this Run() is in the new thread owned by the TThread class. b) When you call Start() will your new thread object, TThread creates a new windows thread and makes it call your Run() function c) You have to be aware of the valid states and state transitions. For example, when you create a new TThread object, it is in the TThread::Created state. The only valid transition is to TThread::Running (this is done by calling Start()). So in other words, you can't create a TThread object and not call its Start(). If you try to delete this object before calling Start(), it will throw an exception. Also, the new thread is done when you return from Run() or when you call Exit() (i think). Basically, you must call Start() exactly once for each instance of TThread. This means that you must call Start() before deleting the object and you can only can Start() once during the lifetime of the object. All this kind of stuff is in the docs, but I thought I would mention it anyway. If you want a slick way of controlling a thread without being required to derive from it, check out the code below. Basically, any class that needs multithreading, just derive from Runnable and override int Run(). When you're ready, you can create a new ThreadEx object like: // assuming 'this' is an instance of an object derived // from Runnable // ThreadEx* mythread = new ThreadEx(this); myThread->Start(); you now have an object that can USE threads without being a thread object itself and without having to create a separate DoSomethingInAnotherThread class derived from TThread every time you need another functionality in separate thread. The object using a ThreadEx can create a new thread, run it, delete it, create another, run it, delete it .... Here is the code: // // declaration // class ThreadEx; class Runnable { public: Runnable(); protected: virtual int Run() = 0; friend ThreadEx; }; class ThreadEx : public TThread { public: ThreadEx(Runnable* runnable); virtual ~ThreadEx(); int Run(); bool ShouldTerminate(); TThread::THandle Start(); TThread::THandle GetHandle(); void Kill(); protected: Runnable* runnable; TThread::THandle threadHandle; }; // // // Runnable implementation // Runnable::Runnable() { } // // // ThreadEx implementation // ThreadEx::ThreadEx(Runnable* runnable) { if(runnable == NULL) xmsg("ThreadEx: Invalid Runnable").raise(); this->runnable = runnable; } ThreadEx::~ThreadEx() { switch(GetStatus()) { case Created: Start(); case Suspended: Resume(); case Running: TerminateAndWait(5000); if(GetStatus() != Finished) Kill(); break; } } TThread::THandle ThreadEx::Start() { threadHandle = TThread::Start(); return threadHandle; } TThread::THandle ThreadEx::GetHandle() { return threadHandle; } // // Avoid using Kill(). It will obliterate the thread and any resources that were allocated by // your code will not be freed. // void ThreadEx::Kill() { ::TerminateThread(threadHandle, 0); } bool ThreadEx::ShouldTerminate() { return TThread::ShouldTerminate(); } int ThreadEx::Run() { return runnable->Run(); } 7/2/98 10:32:32 AM
Last Modified: 01-SEP-99