当前位置:  开发笔记 > 编程语言 > 正文

为什么循环变量的值不存储在动态创建的AnonymousThread中

如何解决《为什么循环变量的值不存储在动态创建的AnonymousThread中》经验,为你挑选了1个好方法。

我对如何在动态创建中存储唯一标识符有一些学术兴趣TThread.

我创建这样的东西:

procedure TForm1.Button1Click(Sender: TObject);
var thrn:word;
begin
for thrn := 0 to 5 do//<--- this is a loop variable that should give the unique numbers
  TThread.CreateAnonymousThread(
    procedure()
    var
      i: longint;
      r: double;
      thrns:string;
    begin
      thrns:=inttostr(thrn);//in this thread? variable I try to store the ID as string
      repeat
        for i := 0 to 100000000 do
        begin
          r := random(high(i));//this loop gives some dummy job 
          r := sqr(r);         //to the thread to slow it down
        end;
        TThread.Synchronize(nil,
          procedure()
          begin
            memo1.Text:=memo1.Text+#13#10+
              'done'+thrns;//it returns strange IDs including '6'
          end);
      until false;
    end).Start;
end;

我可以将唯一标识符传递给动态创建的线程,以便它可以在同步方法中显示它吗?



1> David Heffer..:

这是一个经典的误解.我们理解匿名方法捕获,但它们捕获了什么?价值或变量?

答案是后者.他们捕获变量.有一个变量,thrn您的六个匿名方法中的每一个都会捕获.由于存在一个变量,因此在任何一个时刻只有一个值.

当然,由于您在线程中执行代码,因此您对此变量进行了数据竞争.因此,我的"在任何一个时刻"附带条件.这就是为什么你有不可重复的,不可预测的结果.并且您可能在循环完成后访问循环变量,然后该值未定义.

如果希望为每个匿名方法设置不同的值,则必须为每个匿名方法创建一个新变量.我对另一个问题的回答表明:匿名方法 - 变量捕获与值捕获.

因此,为了在您的上下文中说明,我们需要更多的脚手架.

function GetThreadProc(thrn: Integer): TProc;
begin
  Result := 
    procedure
    begin
      // thrn is passed by value, so a copy is made, i.e. a new variable
      ....
    end;
end;

....

procedure TForm1.Button1Click(Sender: TObject);
var 
  thrn: Integer;
begin
  for thrn := 0 to 5 do
    TThread.CreateAnonymousThread(
      GetThreadProc(thrn)).Start;
end;

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有