gpt4 book ai didi

程序终止后的Delphi任务和线程

转载 作者:行者123 更新时间:2023-12-01 18:59:05 24 4
gpt4 key购买 nike

我有一个疑问,无法在网上或在我的 delphi 书中解决。看看这个。

情况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;

这是 VCL 实现:

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

我打开程序,单击按钮,等待 5 秒钟,然后在桌面上看到该文件。但是,如果我打开程序,单击按钮,2 秒后关闭程序,我就看不到该文件了(5 秒后)。

我读了 nick hodges 的更多 delphi 编码,他说这种线程是 F&F(“Fire and Forget”),因为一旦启动,我们就放开它,它会自行清理。如果我终止之前关闭该程序,它会被正确终止吗?

情况 2。出于好奇,我也编写了这段代码:

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;

这是案例 1 中的代码,但由于我使用了任务,所以输入量较少。在这种情况下,事情就不同了!

如果我运行该程序,单击按钮并等待 5 秒钟,我就可以看到该文件。如果我运行该程序,单击按钮,然后在 2 秒后(或在任何情况下,5 秒前)关闭程序,我仍然会看到文本文件!

<小时/>
  • 任务。一旦启动,它就会运行到最后,无论我是否在终止之前关闭程序。
  • TThread 子类。一旦启动,它将运行到最后,但是如果我在终止之前关闭程序,它就会死掉(?)

正如上面已经问到的,我想知道(在情况 1 中)是否可以在线程终止之前关闭程序。因为我认为我可以这样写:

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

基本上,我不确定是否必须在代码中调用Terminate,或者当程序终止时是否会以某种方式自动调用它。从我的测试来看,这仅影响 TThread 后代,而不影响任务。

最佳答案

这与文件无关。不幸的是,与处理任务的方式相比,Delphi 运行时处理线程的方式存在差异。

当您退出 VCL 应用程序时,后台线程将被终止。应用程序不会等待它们,它就会结束。如果你想等他们,你就必须自己编写代码。

但是,VCL 应用程序将等待(如有必要,将永远等待)放入默认线程池 ( System.Threading.TThreadPool.Default ) 中的所有任务。

考虑这个示例 VCL 应用程序:带有两个按钮的空表单:

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;

在调试器中运行此应用程序。您会注意到,对于 Button1,您的应用程序将立即退出。对于 Button2,您的程序似乎消失了(表单已关闭),但它仍在运行!最后,五秒钟后,您的调试器将在 Winapi.Windows.DebugBreak() 处中断。 .

奖金:更改TTask.Run(backgroundStuff);TTask.Run(backgroundStuff, TThreadPool.Create());看看会发生什么。

关于程序终止后的Delphi任务和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382872/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com