Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi Tasks and Thread after program termination

Tags:

delphi

I got a doubt that I wasnt able to solve online or in my delphi books. Look at this.

Case 1.

type
  Test = class(TThread)
    protected
      procedure Execute; override;
    public
      constructor Create;
  end;

constructor Test.Create;
begin
  inherited Create(false);
  FreeOnTerminate := true;
end;

procedure Test.Execute;
begin
  inherited;
  Sleep(5000);
  TFile.WriteAllText('C:\Users\EmmaVMWare\Desktop\ts.txt', 'test2');
end;

And this is the VCL implementation:

procedure TForm1.Button1Click(Sender: TObject);
var s: Test;
begin
  s := Test.Create;
  s := nil;
end;

I open the program, I click the button, I wait 5 seconds and I see the file on the desktop. But if I open the program, I click the button and after 2 seconds I close the program, I don't see the file anymore (after the 5 seconds).

I read nick hodges' more coding in delphi and he said that this kind of thread is F&F ("Fire and forget") because once started we let it go and it will cleanup by itself. If I close the program before its termination, will it be properly killed?

Case 2. Out of curiosity I've written this code as well:

procedure TForm1.Button1Click(Sender: TObject);
var s: ITask;
begin

  s := TTask.Run(procedure
                 begin
                  Sleep(5000);
                  TFile.WriteAllText('C:\Users\EmmaVMWare\Desktop\aa.txt', 'test');
                 end);
end;

That is the code in Case 1 but with less typing because I've used a Task. In this case things are different!

If I run the program, click the button and wait 5 seconds I can see the file. If I run the program, click the button and then I close the program after 2 seconds (or in any case, before 5 seconds) I still see the text file!


  • Task. Once started it will run until the end, no matter if I close the program before its termination.
  • TThread subclass. Once started it will run until the end BUT if I close the program before its termination it will die (?)

As already asked above, I'd like to know if (in Case 1) is fine to just close the program before the termination of the thread. Because I thought that I could have written this:

procedure TForm1.FormDestroy(Sender: TObject);
begin
   if not(s.Terminated) then
     s.Terminate;
end;

Basically I am not sure if I have to call Terminate in code or if it's called automatically somehow when the program dies. From what I've seen by my tests, this affects only TThread descendants and NOT Tasks.

like image 575
Emma Rossignoli Avatar asked Oct 20 '25 03:10

Emma Rossignoli


1 Answers

This has nothing to do with files. It is the unfortunate difference how the Delphi runtime handles threads, compared to how it handles tasks.

When you exit a VCL application, the background threads are just killed off. The application does not wait for them, it just ends. If you want to wait for them, you will have to write the code yourself.

A VCL application, however, will wait (for all eternity, if necessary) for all the tasks that were put in the default thread pool (System.Threading.TThreadPool.Default).

Consider this example VCL application: Empty form with two buttons:

implementation uses System.Threading, Winapi.Windows;

procedure TForm1.Button1Click(Sender: TObject);
begin
    TThread.CreateAnonymousThread(backgroundStuff).Start();
    Application.Terminate();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    TTask.Run(backgroundStuff);
    Application.Terminate();
end;

procedure TForm1.backgroundStuff();
begin
    Sleep(5000);
    Winapi.Windows.DebugBreak();
end;

Run this application in your debugger. You will notice that for Button1, your application will exit immediately. For Button2, your program appears to be gone (the form has been closed), but it's still running! Finally, after five seconds, your debugger will break on Winapi.Windows.DebugBreak().

Bonus: Change TTask.Run(backgroundStuff); to TTask.Run(backgroundStuff, TThreadPool.Create()); and see what happens.

like image 72
Günther the Beautiful Avatar answered Oct 22 '25 03:10

Günther the Beautiful