[DUG] Terminating a thread

Todd Martin toddm at kol.co.nz
Fri Sep 22 10:07:52 NZST 2006


What does your thread actually do?
Using Sleep() inside the thread will not "freeze" your program.

----- Original Message ----- 
From: "Nick Fauchelle" <nick at unica.co.nz>
To: "NZ Borland Developers Group - Delphi List" <delphi at ns3.123.co.nz>
Sent: Friday, September 22, 2006 9:37 AM
Subject: Re: [DUG] Terminating a thread


> 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
>>
>>
>>
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
>
>
>
>
> -- 
> No virus found in this incoming message.
> Checked by AVG Free Edition.
> Version: 7.1.405 / Virus Database: 268.12.6/453 - Release Date: 20/09/2006
> 



-- 
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.405 / Virus Database: 268.12.6/453 - Release Date: 20/09/2006



More information about the Delphi mailing list