首页 > 解决方案 > 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:正如我所说的只是第一个周期而不发送到新线程。其他线路正在发送和处理就好了!

标签: multithreadingdelphi

解决方案


问题是匿名方法捕获变量。因为变量被捕获,所以它的值在主循环期间发生变化。基本上所有线程共享相同的变量。线程与主循环并行运行,并且没有排序约束。因此,主循环完全有可能在您的一个线程有机会使用该值之前修改捕获的变量。

您的代码将使用值捕获(与变量捕获相反)。不直接支持取值,但很容易模拟相同的效果。请参阅匿名方法 - 变量捕获与值捕获

我会评论说,这个线程代码将比串行代码慢。你希望达到什么目标?


推荐阅读