在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柏林
编辑:
按照的建议,我重写了代码--这是正确的吗?:
// 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;发布于 2017-05-03 19:45:48
您需要使用锁来修改复杂的数据类型,如string。这不可能是原子性的。
如果您只针对Windows,请使用TCriticalSection。对于针对其他平台的代码,您应该使用TMonitor。
发布于 2017-05-03 20:13:15
另一种选择是使用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;https://stackoverflow.com/questions/43768196
复制相似问题