Now we've covered the background, lets look at some code. First off, the basics of a thread.
Code:
interface uses classes; type TVerySimpleThread = class(TThread) protected fCounter : integer; public procedure execute; override; end; implementation procedure TVerySimpleThread.execute; begin while not self.terminated do fCounter:=fCounter+1; end;
But what happens next?
Well that depends on how you want to handle things. You have several different options relating to terminating and cleaning up your thread and your choice will be governed by how you are using the thread object. The options you have are 'fire and forget', 'application notification', 'terminate on demand'.
Fire and Forget
To implement a fire and forget thread, then you need to consider the 'freeOnTerminate' property, but you also need to ensure that your application either does not need to access these spawned threads or if it does, that it can cope with potentially not being able to gain access to the thread object (it may have terminated and been freed). Once your thread has done its job, it can end by leaving the 'execute' method.
Code:
// The nice way to create a 'fire and forget' thread (use a temporary variable) myThread:=TMyThreadClass.create(false); myThread.freeOnTerminate:=true; // And the dirty (true fire and forget) way... TMyThread.create(false).freeOnTerminate:=true;
Application Notification
If you want the thread to let your main application to know its terminated, you can provide a handler for the 'OnTerminated' event. This is a standard TNotify event (procedure(sender:TObject) of object). When the thread terminates, this handler is called and you can take any action you deem appropriate (including freeing up the thread object). But, bear in mind that if you've already set the 'freeOnTerminate' property to true and you free the thread in the OnTerminate event handler, you will be faced with an access violation as the system attempts to free the thread itself when it returns from the event handler.
Code:
... myThread.onTerminate:=form1.myOnTerminateHandler; ... procedure TForm1.myOnTerminateHandler(sender:TObject); begin // Sender points to the TThread descendant that is ending sender.free; end;
Terminate on Demand
The final key choice you have for handling the termination of a thread is what I would call 'Terminate on Demand'. This method of terminating a thread does not rely on using the 'freeOnTerminate' property or the 'onTerminate' event handler as you explicitly terminate the thread and then wait for it to finish. You can use 'freeOnTerminate' or the 'onTerminate' event handler to free up the thread, but if you are explicitly requesting the termination of the thread, its just as easy to free it up yourself when its completely finished.
Code:
... // Create our thread and grab it myThread:=TMyThread.create(false); ... ... // Terminate our thread myThread.terminate; // Wait for it to finish up myThread.waitFor; // And free it myThread.free; ...
vBulletin Message