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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Conor Boyd
Sent: Thursday, 21 September 2006 2:49 p.m.
To: [EMAIL PROTECTED]; 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
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:[EMAIL PROTECTED]
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
[email protected]
http://ns3.123.co.nz/mailman/listinfo/delphi
_______________________________________________
Delphi mailing list
[email protected]
http://ns3.123.co.nz/mailman/listinfo/delphi
_______________________________________________
Delphi mailing list
[email protected]
http://ns3.123.co.nz/mailman/listinfo/delphi