此问题在此处已有答案:
How the variable capturing in anonymous functions works in Delphi TTask - PPL?(1个答案)
11天前关闭。
给出以下代码:
procedure TForm1.Button1Click(Sender: TObject);
var
myTask: ITask;
begin
myTask := TTask.Run(
procedure
var
i: Integer;
begin
for i := 0 to 3 do
begin
TThread.ForceQueue(
nil
, procedure
begin
ShowMessage('Count: ' + i.ToString);
end
);
//I know this will work
// TThread.Synchronize(
// nil
// , procedure
// begin
// ShowMessage('Count: ' + i.ToString);
// end
// );
end;
end
);
end;
这将始终打印“计数:4寸
有没有办法在执行排队的匿名过程时保留变量i
?
我知道使用Synchronize()
可以工作,但我更喜欢使用Queue
,因为在我的真实的情况中,queued方法会在文件中写入一些日志。我的任务不需要等待日志,这就是为什么我更喜欢使用Queue()
。
我用的是 Delphi 10.3。
1条答案
按热度按时间wxclj1h51#
首先,您应该使用
TThread.Queue()
而不是TThread.ForceQueue()
。后者只用于主UI线程,而不是任务线程。其次,匿名方法捕获变量引用,而不是值。请阅读documentation,特别是“变量绑定机制”一节。您正在排队4个共享单个变量的匿名方法,这就是为什么它们的结果都是相同的值。
要解决这个问题,请将捕获移到另一个过程中,这样匿名方法就不再共享单个变量。例如: