Reputation: 407
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
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