[DUG] Terminating a thread

Conor Boyd Conor.Boyd at trimble.co.nz
Thu Sep 21 17:49:04 NZST 2006


I'm not sure initially, but you may have to look at having your
application (i.e. the main VCL thread) wait at shutdown time until your
sub thread has successfully terminated after being told to do so.

The other thing is that using Ttimer in a thread may be well dodgy, but
that's just a hunch.  Why are you having to use a timer?

I haven't had to do that myself before, and I'm not sure what the timer
is doing that's weird.

Look at calling WaitForSingleObject from the main VCL thread or similar,
and see if that helps.  I can't help you with that straight off, as I
haven't had to do that before.

Good luck.  If I think of anything else, I'll let you know.

HTH,

Conor

-----Original Message-----
From: delphi-bounces at ns3.123.co.nz [mailto:delphi-bounces at ns3.123.co.nz]
On Behalf Of Nick Fauchelle

Hmmm ok,
So I got that going, and all seems well  - my thread has set
freeonterminate := true; when it was created.
But when I terminate it (try) it seems to work, except when I then close
the application I get a Access Violation error..

This only happens when I have objects freeing in my destructor like so
begin
  ProgTimer.Free;
  ADOQ1.Free;
  IdHttp.Free;
  inherited;
end;

However, if I don't have them there - my ProgTimer (TTimer) still counts
the count, even if I terminate the thread...
that was created like so in the creator
----
  ProgTimer           := TTimer.Create(nil);
  ProgTimer.OnTimer   := ProgTimerTimer;
  ProgTimer.Interval  := 1000;
  ProgTimer.Enabled   := true;

  Both ProgTimer : TTimer and it's OnTimer event are declared in the
private section of my thread.
---

Im thinking it may have something to do with the nil.

So,
If I terminate, ProgTimer.OnTimer will still fire.
If I call ProgTimer.Free with the destructor then the timer stops
firing, but the program access violations when I close it.

:-)



Conor Boyd wrote:
> Once the Execute method of your thread class finishes, then your 
> thread is done working.  The only way to keep a thread doing stuff is 
> to have a loop like the While not Terminated do... one I listed.
>
> Exit causes that loop to finish, and therefore your thread to finish.
>
> How the thread is freed is up to you.  If you set the FreeOnTerminate 
> property to True in your constructor, then your thread will free 
> itself after the Execute method finishes, so you don't have to worry
about it.
>
> Your TFetchData class can have a Destructor (Destroy) method just like

> any other class.  That would be the place to tidy up things like 
> Tidhttp.
>
> Here's a rough example of the way I work with threads. This sort of 
> thread is told "go and do stuff and I don't need to hear from you
again"
> sort of thing.
>
> TMyThread = class(Tthread);
> Private
>   FSomeObject: Tobject;
> Public
>   constructor Create(SomeParams: TSomeParams);
>   destructor Destroy; override;
>   procedure Execute; override;
> End;
>
> Constructor TMyThread.Create(SomeParams: TSomeParams); Begin
>   inherited Create(True); // Creates thread suspended so that we can 
> set fields etc.
>
>   FreeOnTerminate := True; // Thread will terminate itself.
>
>   FSomeObject := Tobject.Create;
>
>   DoSomethingWithSomeParams;
>
>   Resume; // Now tell the thread to do its stuff in the Execute method

> End;
>
> Destructor TMyThread.Destroy;
> Begin
>   FSomeObject.Free;
>   inherited;
> End;
>
> Procedure TMyThread.Execute;
> Begin
>   while not Terminated do
>   try
>     DoSomeStuff;
>
>     if Terminated then
>       Exit; //Causes Execute method to finish, and therefore Thread 
> object to free itself
>
>     DoSomeMoreStuff;
>   catch
>     on E:Exception
>       // Do Something with Exception
>   end;
> End;
>
> HTH,
>
> Conor
>
> -----Original Message-----
> From: Nick Fauchelle [mailto:nick at unica.co.nz]
>
> Thanks for the quick response.
> Does the exit just exit the try statement (or is that break; im 
> thinking about).
> So if there was code at the end of the thread, would it still run?
>
> Also, I assume anything I create
> like
> myHttp := TidHttp.create(nil); in the creator I should myHttp.free; in

> the OnTerminate?
>
> Just checking ;-)
>
>
> Conor Boyd wrote:
>   
>> You're nearly there, I think.
>>
>> TThread has a Terminated property already. 
>>
>> When you call the existing Terminate method on TThread, it simply 
>> sets
>>     
>
>   
>> the Terminated property to True.
>>
>> It's up to you to check the value of Terminated while your thread is 
>> processing.
>>
>> E.g.
>>
>> Procedure TFetchData.Execute;
>> begin
>>   while not Terminated do
>>   try
>>     DoSomeStuff;
>>
>>     if Terminated then
>>       Exit;
>>
>>     DoSomeMoreStuff;
>>
>>     if Terminated then
>>       Exit;
>>
>>     DoEvenMoreStuff;
>>   catch
>>     on E: Exception do
>>       // Never let exceptions percolate out of your thread.
>>   end
>> end;



More information about the Delphi mailing list