ZXing.Delphi - 正确使用TThread.Synchronize?

时间:2017-06-19 10:25:56

标签: multithreading delphi firemonkey zxing

我正在开始一个FMX / Android应用程序中的条形码阅读项目(条形码阅读新手,我对FMX有一些经验)。

我发现这个开源ZXing.Delphi library(非常有帮助),我浏览了this example的代码。

我对TThread的使用可能不够,但我想知道在这种情况下使用TThread.Synchronize,因为我之前从未见过/使用过它。

1 - 负责捕获+扫描图像以搜索条形码的功能是GetImage。它与CameraComponent1SampleBufferReady上的主线程同步。

procedure TMainForm.CameraComponent1SampleBufferReady(Sender: TObject;
  const ATime: TMediaTime);
begin
  TThread.Synchronize(TThread.CurrentThread, GetImage);
end;

2 - GetImage函数包含TTask.Run,它再次使用TThread.Synchronize同步到主线程。

procedure TMainForm.GetImage;
var scanBitmap: TBitmap; ReadResult: TReadResult;
begin

  CameraComponent1.SampleBufferToBitmap(imgCamera.Bitmap, True);

...

  scanBitmap := TBitmap.Create();
  scanBitmap.Assign(imgCamera.Bitmap);
  ReadResult := nil;

  // There is bug in Delphi Berlin 10.1 update 2 which causes the TTask and
  // the TThread.Synchronize to cause exceptions.
  // See: https://quality.embarcadero.com/browse/RSP-16377

  TTask.Run(
  procedure
  begin
    try
      FScanInProgress := True;
      try
        ReadResult := FScanManager.Scan(scanBitmap);
      except
        on E: Exception do
        begin
          TThread.Synchronize(nil,
          procedure
          begin
            lblScanStatus.Text := E.Message;
          end);

          exit;
        end;
      end;

      TThread.Synchronize(nil,
      procedure
      begin

        ...

        if (ReadResult <> nil) then
        begin
          Memo1.Lines.Insert(0, ReadResult.Text);
        end;

      end);

    finally
      ReadResult.Free;
      scanBitmap.Free;
      FScanInProgress := false;
    end;

  end);

end;

封装TThread.Synchronize(TTask.Run(TThread.Synchronize(...)))是否是通常/良好的实践; ?

? :难道不是Delphi 10.1 update 2中遇到的提及异常的原因吗?

当我“学会”使用并行编程库时,我主要使用:

我在某处错过了吗?

1 个答案:

答案 0 :(得分:0)

快速更新。使用Embarcadero 10.3.1:

TThread.Synchronize(TThread.CurrentThread, GetImage);

在随机数秒后生成分段错误。 您会注意到调试过程中发生了许多“切换到线程”调用,它将始终使APP崩溃。 无论是否将GetImage函数保留为空。 我尝试了所有可能的方式,但我的应用程序以及原始应用程序崩溃了。 我也尝试过创建一个Asyincronous线程以及Labda……一直都得到相同的结果 看起来TThread同步在10.3.1上有问题。其他用户报告说它可以在以前的东京版本上正常工作。

您身边有任何反馈意见吗?