SteveS
SteveS

Reputation: 407

Delphi What happens when the app terminates while a thread is waiting on an event?

I have a thread that loops performing work and sleeping via an event for a good bit of time (several seconds.) The user can terminate the app while the thread is asleep waiting on the event. What actually happens to the event in that case? Does the thread keep running until the event times out, delaying the full termination of the app? Or does it return immediately with a return value other than timeout?

Upvotes: 2

Views: 444

Answers (1)

user3810626
user3810626

Reputation: 7709

While it is not impossible to start processes that outlive the Delphi app that created them, threads created and started in the usual manner (via TThread.Create) end as soon as the main thread ends, without waiting for a cycle to complete and without holding up the termination of the main app.

To convince yourself of this, create a Delphi app and a thread that is started by clicking a button. Have the thread write to a file, then sleep for an arbitrarily large amount of time. When you're sure it's asleep, kill the app. Note that the app terminates immediately, and also the thread is "killed in its sleep".

In fact, if we add a finalization section:

type
  TTThread = class(TThread)
       msg : string;
       ctr : Integer;
    public procedure Execute; override;
    procedure Update;
  end;

procedure TTThread.Execute;
var F: TextFile;
begin
  ctr := 0;
  assignFile(F, 'log.txt');
  rewrite(f);
  closefile(f);
  while not Terminated do
  begin
      inc(ctr);
      msg := 'Updating';
      Synchronize(Update);
      assignFile(F, 'log.txt');
      append(f);
      writeln(F, IntToStr(Ctr));
      closefile(f);
      msg := 'Sleeping';
      Synchronize(Update);
      Sleep(3000);
  end;
end;

procedure TTThread.Update;
begin
   Form1.Caption := '**********'+msg+IntToStr(ctr)+'******************';
end;

var T: TTThread;
procedure TForm1.Button1Click(Sender: TObject);
begin
   if not assigned(T) then T := TTThread.Create(false);
end;


var F: TextFile;
initialization
finalization
      assignFile(F, 'log.txt');
      append(f);
      writeln(F, 'Application out!');
      closefile(f);
end.

(N.B. this is not presented as thread-safe code but it is useful for experimentation.) You can set your debugger at the last closeFile in the finalization and park it there as long as you like and the thread will not write to the file again. This tells us that by the time the finalization code hits, owned threads are already dead.

Depending on your level of interest, you can also check in the OnClose of the form, override the Close method for your main form, etc.

This leaves some holes in our understanding, like whether the main form formally terminates each thread, but I trust from this you can figure out how you would test that. (A quick scan of the Form source was not especially revealing.)

Upvotes: 2

Related Questions