Multithreading Delphi 10.4 FMX应用程序用线程替换Application.ProcessMessage()

Multithreading Delphi 10.4 FMX应用程序用线程替换Application.ProcessMessage(),multithreading,delphi,Multithreading,Delphi,我正在尝试运行一个简单的Delphi 10.4 FMX程序示例,该程序按照和的建议取消了Application.ProcessMessages() 该按钮仅更新标签3次。接下来,它在一个级别(而不是两个级别)上按预期工作 有人能指出我做错了什么吗?我将代码留给了Application.ProcessMessages(),以显示所需的效果 函数Measure1sec(等待:整数):布尔值; 变量 sw:TStopwatch; 开始 sw:=TStopwatch.StartNew; 而sw.elap

我正在尝试运行一个简单的Delphi 10.4 FMX程序示例,该程序按照和的建议取消了
Application.ProcessMessages()

该按钮仅更新标签3次。接下来,它在一个级别(而不是两个级别)上按预期工作

有人能指出我做错了什么吗?我将代码留给了
Application.ProcessMessages()
,以显示所需的效果

函数Measure1sec(等待:整数):布尔值;
变量
sw:TStopwatch;
开始
sw:=TStopwatch.StartNew;
而sw.elapsedmillesons
首先,您的
Measure1sec()函数效率低下。在繁忙循环中不使用
TStopWatch
,而是可以将其重新写入使用,例如:

过程测量1秒(等待:整数);内联;
开始
TThread.Sleep(等待);
结束;
在这种情况下,您也可以完全去掉
Measure1sec()
,例如:

label1.text:='apple';
//Application.ProcessMessages;
TThread.Sleep(500);
label1.text:=“橙色”;
//Application.ProcessMessages;
TThread.Sleep(500);
label1.text:=“完成”;
//Application.ProcessMessages;
TThread.Sleep(500);
现在,为了回答您的问题,您没有看到所有的标签更新,因为您的工作线程只执行一次标签更新。对于您正在尝试的内容,您需要让线程执行多个标签更新,例如:

procedure TForm1.按钮1点击(发送方:TObject);
开始
TThread.CreateAnonymousThread(
程序
开始
TThread.Synchronize(nil,
程序
开始
标签1.text:=“苹果”;
结束
);
TThread.Sleep(500);
TThread.Synchronize(nil,
程序
开始
label1.text:=“橙色”;
结束
);
TThread.Sleep(500);
TThread.Synchronize(nil,
程序
开始
label1.text:=“完成”;
结束
);
TThread.Sleep(500);
结束
).开始;
结束;
但是,这在很大程度上是对工作线程的浪费,因为大部分工作都是在主UI线程中执行的。因此,我建议完全摆脱
TThread
,改用,例如:

procedure TForm1.按钮1点击(发送方:TObject);
开始
步骤1;
结束;
程序TForm1.Step1;
开始
标签1.text:=“苹果”;
ForceQueue(nil,步骤2500);
结束;
程序TForm1.Step2;
开始
label1.text:=“橙色”;
ForceQueue(nil,步骤3500);
结束;
程序TForm1.Step3;
开始
label1.text:=“完成”;
结束;
或者:

procedure TForm1.按钮1点击(发送方:TObject);
开始
标签1.text:=“苹果”;
TThread.ForceQueue(nil,
程序
开始
label1.text:=“橙色”;
完,,
500
);
TThread.ForceQueue(nil,
程序
开始
label1.text:=“完成”;
完,,
1000
);
结束;

首先,您的
Measure1sec()函数效率低下。在繁忙循环中不使用
TStopWatch
,而是可以将其重新写入使用,例如:

过程测量1秒(等待:整数);内联;
开始
TThread.Sleep(等待);
结束;
在这种情况下,您也可以完全去掉
Measure1sec()
,例如:

label1.text:='apple';
//Application.ProcessMessages;
TThread.Sleep(500);
label1.text:=“橙色”;
//Application.ProcessMessages;
TThread.Sleep(500);
label1.text:=“完成”;
//Application.ProcessMessages;
TThread.Sleep(500);
现在,为了回答您的问题,您没有看到所有的标签更新,因为您的工作线程只执行一次标签更新。对于您正在尝试的内容,您需要让线程执行多个标签更新,例如:

procedure TForm1.按钮1点击(发送方:TObject);
开始
TThread.CreateAnonymousThread(
程序
开始
TThread.Synchronize(nil,
程序
开始
标签1.text:=“苹果”;
结束
);
TThread.Sleep(500);
TThread.Synchronize(nil,
程序
开始
label1.text:=“橙色”;
结束
);
TThread.Sleep(500);
TThread.Synchronize(nil,
程序
开始
label1.text:=“完成”;
结束
);
TThread.Sleep(500);
结束
).开始;
结束;
但是,这在很大程度上是对工作线程的浪费,因为大部分工作都是在主UI线程中执行的。因此,我建议完全摆脱
TThread
,改用,例如:

procedure TForm1.按钮1点击(发送方:TObject);
开始
步骤1;
结束;
程序TForm1.Step1;
开始
标签1.text:=“苹果”;
ForceQueue(nil,步骤2500);
结束;
程序TForm1.Step2;
开始
label1.text:=“橙色”;
ForceQueue(nil,步骤3500);
结束;
程序TForm1.Step3;
开始
label1.text:=“完成”;
结束;
阿尔特