jim*_*web 1 delphi performance pascal delphi-xe2
我正在尝试下面的代码.但是,如果在此代码运行时单击窗体的关闭按钮,则不会发生任何操作.我怎么能纠正这个?即使执行此循环,我也需要关闭表单.
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 9999999 do
begin
Memo1.Lines.Add('hi');
Application.ProcessMessages;
end;
end;
Run Code Online (Sandbox Code Playgroud)
Mas*_*ler 13
看看里面发生了什么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;
Run Code Online (Sandbox Code Playgroud)
我想这是不是一个CLR程序,所以出现这种情况在这一点的唯一事情是设置FTerminate := True上Application.这反映在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;
Run Code Online (Sandbox Code Playgroud)
另外,请注意Application.ProcessMessages首先使用,因为它将处理应用程序的所有消息.对于什么可能出错一个简单的想法,尝试加入IntToStr(i)的,而不是'hi'来Memo1.Lines,磕了几个量级关闭计数器的订单,然后按一下按钮两次或三次快速连续并观察输出...
检查Apllication终止:
for i := 0 to 9999999 do
begin
Memo1.Lines.Add('hi');
Application.ProcessMessages;
if Application.Terminated then Exit;
end;
Run Code Online (Sandbox Code Playgroud)