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

Reply via email to