gpt4 book ai didi

performance - 为什么在 Delphi 中运行巨大的 for 循环时没有发生 'form close' 事件?

转载 作者:行者123 更新时间:2023-12-03 17:45:35 25 4
gpt4 key购买 nike

我正在尝试以下代码。但是,如果我在此代码运行时单击表单的关闭按钮,则不会发生任何事情。我该如何纠正?即使在执行此循环时,我也需要关闭表单。

procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 9999999 do
begin
Memo1.Lines.Add('hi');
Application.ProcessMessages;
end;
end;

最佳答案

看看 Application.ProcessMessages 内部发生了什么。

当您关闭主窗体时,Windows 会向程序发送一条 WM_QUIT 消息。 TApplication.ProcessMessages 的相关部分如下所示:

    if Msg.Message <> WM_QUIT then
begin
//skipped
end
else
begin
{$IF DEFINED(CLR)}
if Assigned(FOnShutDown) then FOnShutDown(self);
DoneApplication;
{$IFEND}
FTerminate := True;
end;

我假设这不是 CLR 程序,所以此时唯一发生的事情就是在 FTerminate := True 上设置 Application 。这反射(reflect)在 Application.Terminated 属性中。

当应用程序关闭时,它为了安全关闭所做的事情之一就是等待所有线程完成。这段代码恰好在主线程中运行,但原理在任何线程中都是相同的:如果您正在执行可能必须提前完成的长时间运行的任务,则必须明确检查是否提前终止。

知道了这一点,很容易弄清楚如何修复你的代码:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 9999999 do
begin
Memo1.Lines.Add('hi');
Application.ProcessMessages;
if Application.Terminated then
Break;
end;
end;

此外,请注意首先使用 Application.ProcessMessages,因为它将处理应用程序的所有消息。对于可能出错的简单想法,请尝试将 IntToStr(i) 而不是 'hi' 添加到 Memo1.Lines ,从柜台上敲几个数量级,然后快速连续单击按钮两到三下并观察输出......

关于performance - 为什么在 Delphi 中运行巨大的 for 循环时没有发生 'form close' 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16922758/

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