我创建了一个通用线程类,它控制一个进度表单,该表单被注入(inject)线程的构造函数并设置为 _progressForm 。在 Execute 方法中,线程初始化表单并使用函数 ShowModal() 显示它,如下所示:

procedure TProgressThread.Execute;
begin
  ...
  ShowForm;
end;

procedure TProgressThread.ShowForm;
begin
  if Assigned(_progressForm) then
  begin
    Synchronize(
      procedure
      begin
        _progressForm.ShowModal();
      end);
  end;
end;

我不明白的是为什么我的线程被锁定在同步?在进度表关闭之前它不会返回。 ShowModal 不应该只锁定主线程吗?

最佳答案

TThread.Synchronize() 同步 。它阻塞调用线程,直到同步代码从主线程返回。
ShowModal() 也是 同步 。它阻塞调用线程,直到窗体关闭。

所以,当Synchronize()在主线程调用ShowModal()时,Synchronize()在Form关闭之前不会返回到工作线程。

如果您不想阻塞工作线程,请使用 TThread.Queue() 而不是 TThread.Synchronize() ,或者使用 TForm.Show() 而不是 TForm.ShowModal()

进度显示不应阻止工作线程执行其工作。您应该让线程 异步地将进度更新 发布到主线程,并让主线程决定如何在线程继续工作时显示状态。工作线程应该对 UI 一无所知。

10-05 22:26