[DUG] Terminating a thread
Nick Fauchelle
nick at unica.co.nz
Thu Sep 21 17:33:40 NZST 2006
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