在System.Threading.TParallel.For
循环中,我需要写一个字符串变量,该变量在TParallel.For
循环线程之外声明:
// Main thread:
procedure TForm2.GetWeather;
var
CurrentWeather: string;
begin
CurrentWeather := 'Current weather: ';
System.Threading.TParallel.For(1, 10,
procedure(idx: Integer)
begin
if IsRainy(idx) then
begin
// loop thread needs to write-access a mainthread-string-variable:
CurrentWeather := CurrentWeather + 'bad weather, ';
end;
end);
Self.Caption := CurrentWeather;
end;
但根据文档,不应该这样做。并且System.SyncObjs.TInterlocked
似乎没有一种方法可以写入字符串变量。
那么在这种情况下如何写入 CurrentWeather 变量?
Delphi 10.1.2 Berlin
编辑:
按照David Heffernan的建议,我重写了代码 - 这是正确的吗?:
// Main thread:
procedure TForm2.GetWeather;
var
CurrentWeather: string;
ALock: TCriticalSection;
begin
CurrentWeather := 'Current weather: ';
ALock := TCriticalSection.Create;
try
System.Threading.TParallel.For(1, 10,
procedure(idx: Integer)
begin
if IsRainy(idx) then
begin
ALock.Enter;
try
CurrentWeather := CurrentWeather + 'bad weather, ';
finally
ALock.Leave;
end;
end;
end);
finally
ALock.Free;
end;
Self.Caption := CurrentWeather;
end;
答案 0 :(得分:3)
您需要使用锁来修改TCriticalSection
等复杂数据类型。这不能以原子方式完成。
如果您只定位Windows,请使用TMonitor
。对于针对其他平台的代码,您应该使用"arn:aws:s3:::cf-templates-erb4urdcaiht-us-east-1"
。
答案 1 :(得分:0)
另一种选择是使用TThread.Queue
,例如这样(这假设您想要动态更新标题,而不是累积结果并在所有线程完成后显示它)
procedure TForm1.Button6Click(Sender: TObject);
begin
Caption := 'Current weather: ';
TParallel.For(1, 10,
procedure(idx: Integer)
begin
if IsRainy(idx) then
begin
// loop thread needs to write-access a mainthread-string-variable:
TThread.Queue(TThread.Current,
procedure
begin
Caption := Caption + 'bad weather, ';
end)
end;
end);
end;