[DUG] Terminating a thread

Nick Fauchelle nick at unica.co.nz
Fri Sep 22 09:37:57 NZST 2006


Stefan,

I have the TTimer there so I can have a timer displayed on my form so 
the user can see how long the process has taken. Perhaps I should move 
the Timer out of the Thread and have it on the form instead....  and 
then I guess with my OnTerminate I could synchronize a call to 
ProgTimer.Enabled := false.

Would that be a better option?

I couldn't do the sleep option below as im not trying to Sleep the 
program, more just keep a label updated with a count of the time.

Thanks :-)

Stefan Mueller wrote:
> Timers in a thread sounds indeed very dodgy! - TTimer works with windows
> messages (messageloop from your mainthread ... and you are calling into your
> own thread - this is a big no-no!).
>
> Usually a "Sleep(1000);" (or better a Sleep(50); inside 20 loops with a
> check for terminated) in your "Execute" procedure will be a better option.
>
> Regards,
> Stefan
>
>
>
> -----Original Message-----
> From: delphi-bounces at ns3.123.co.nz [mailto:delphi-bounces at ns3.123.co.nz] On
> Behalf Of Conor Boyd
> Sent: Thursday, 21 September 2006 2:49 p.m.
> To: nick at unica.co.nz; NZ Borland Developers Group - Delphi List
> Subject: RE: [DUG] Terminating a thread
>
> 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;
>>>       
>
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
>
>
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
>
>
>   


More information about the Delphi mailing list