Delphi在匿名线程中调用函数?

时间:2019-05-05 10:16:44

标签: multithreading delphi

我必须在一段时间内在匿名线程中调用函数

我的示例函数就是这样,仅用于打印输出:

function processPureTmFrame(rowFrame : string;tmDataGroupRef:string ):string;
    TThread.Synchronize(nil,
      procedure
      begin
         form2.Memo1.Lines.Add( tmSlitFrame );
      end
    );      
end;

当我这样调用函数时:

代码1

while tmBody.Length>0 do
begin
    tmBodyFrameLength := ((hextodec( copy(tmBody,11,2) )+6)*2)+2;
    tmSplitFrame :=  copy(tmBody , 1 , tmBodyFrameLength );
    delete( tmBody, 1, tmBodyFrameLength );

    myThread := TThread.CreateAnonymousThread(
    procedure
    begin
        processPureTmFrame( tmSplitFrame , tmDataGroupRef );
    end);
    myThread.Start;
end;

在循环的第一个周期中,输出丢失

但是当我在没有线程的情况下调用代码时,一切都很好!

代码2

while tmBody.Length>0 do
begin
    tmBodyFrameLength := ((hextodec( copy(tmBody,11,2) )+6)*2)+2;
    tmSplitFrame :=  copy(tmBody , 1 , tmBodyFrameLength );
    delete( tmBody, 1, tmBodyFrameLength );
    processPureTmFrame( tmSplitFrame , tmDataGroupRef );
end;

正确的输出必须是这样

0851C007000C010100000007581850C001F116
0836C0BE001003627169DCA200000000000090D72AACAF
0814C0B6001C03197169DCA31901E2041211131D001F00001F1E1C1F1F1E1E1E0077AA
0814C0B7001E03197169DCA31902FE00540F0000000000000000000000000000000000E238
0814C0B8000B03197169DCA31903FE01384E
0817C0B9000D05017169DCA3E6010190B03F042D
0852C000000B036200000000FAFFFFBF16A3
0852C001000B036200000001F4FF00000000

但是在线程(代码1)中调用时就像

0836C0BE001003627169DCA200000000000090D72AACAF
0814C0B6001C03197169DCA31901E2041211131D001F00001F1E1C1F1F1E1E1E0077AA
0814C0B7001E03197169DCA31902FE00540F0000000000000000000000000000000000E238
0814C0B8000B03197169DCA31903FE01384E
0817C0B9000D05017169DCA3E6010190B03F042D
0852C000000B036200000000FAFFFFBF16A3
0852C001000B036200000001F4FF00000000

没有线程(代码2)的输出没问题

注释#1 :我没有收到类似的错误消息:

  

系统错误。代码:1400。无效的窗口句柄或其他任何东西

注释#2 :正如我所说的,只是第一个周期,而没有发送到新线程。其他行正在发送和处理就很好了!

1 个答案:

答案 0 :(得分:4)

问题在于匿名方法捕获变量。由于捕获了变量,因此其值在主循环中会更改。本质上,所有线程共享相同的变量。线程与主循环并行运行,并且没有排序约束。因此,在您的线程之一有机会使用该值之前,主循环很可能会修改捕获的变量。

您的代码将与值捕获(而不是变量捕获)一起使用。不直接支持值捕获,但是易于模拟相同的效果。参见Anonymous methods - variable capture versus value capture

我要评论一下,尽管此线程代码将比串行代码慢。您希望实现什么?

相关问题