为什么ShowModal会锁定Synchronize?

时间:2017-09-28 21:16:58

标签: delphi

我创建了一个通用线程类来控制一个进程表单,该表单在线程的构造函数中注入并设置为_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;

我无法理解为什么我的线程被锁定在Synchronize?在进度表关闭之前,它不会返回。不应该ShowModal只锁定主线程吗?

1 个答案:

答案 0 :(得分:11)

TThread.Synchronize() 同步。它会阻塞调用线程,直到同步代码从主线程返回。

ShowModal()也是同步。它会阻止调用线程,直到Form关闭。

因此,当Synchronize()在主线程中调用ShowModal()时,Synchronize()将不会返回到工作线程,直到Form关闭。

如果您不想阻止工作线程,请使用TThread.Queue()代替TThread.Synchronize(),或使用TForm.Show()代替TForm.ShowModal()

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