multithreading - 我可以将 Delphi TThread.Synchronize() 本地移动到 VCL 表单以从主线程或工作线程调用吗?

标签 multithreading delphi thread-safety anonymous-methods

我正在将 CreateAnonymousThread 用于工作任务,当我开始使用它时,我根据文档示例在整个声明中使用了 Synchronize,例如:

procedure Txxx.RunWorker;
begin
     FExecutionThread := TThread.CreateAnonymousThread(procedure ()
     begin

        TThread.Synchronize (TThread.CurrentThread,
          procedure ()
          begin
            // Here before worker stuff
            NotifyBeforeWorkerStuff; 

          end);

        // Do worker stuff

        TThread.Synchronize (TThread.CurrentThread,
          procedure ()
          begin
            // Here after worker stuff
            NotifyAfterWorkerStuff;
          end);
      end);

      FExecutionThread.Start;
    end;
end;

如您所见,在此线程中,我向我的应用程序的各个部分启动事件通知,包括 VCL 表单(NotifyBeforeWorkerStuff 等)。 后来,我看到我可以将 Synchronize() 更本地地移动到每个 VCL 表单,接近实际需要它来更新(非安全)VCL 控件的点:

    procedure TSomeVCLForm.ReceiveNotification;
    begin
      TThread.Synchronize (TThread.CurrentThread,
          procedure ()
          begin
            Label1.Caption := GetSomeStringFunction;
          end);
     end;

只要我接受来自主线程或工作线程的通知,工作线程就会变得更简单:

   procedure Txxx.RunWorker;
   begin
     FExecutionThread := TThread.CreateAnonymousThread(procedure ()
       begin

         NotifyBeforeWorkerStuff; 

         // Do worker stuff

         NotifyAfterWorkerStuff;

       end);

     FExecutionThread.Start;
   end;

关于这是否正确,我有几个问题:

  1. 我的通知可能来自工作线程,也可能来自主线程(例如来自按钮按下)。那么,当从主线程调用 VCL 窗体上的“ReceiveNotification”时,是否允许像上面那样调用 TThread.Synchronize? the XE8 docs暗示不是,但检查 System.Classes 这看起来没问题并且工作正常。
  2. 在“ReceiveNotification”中,当 Label1.Caption 从 GetSomeStringFunction 获取字符串时,即使调用来自工作线程,也绝对不需要锁定该函数是否正确?

感谢您的任何建议。

最佳答案

文档说:

Warning: Do not call Synchronize from within the main thread. This can cause an infinite loop.

我认为文档是完全错误的。 XE8 中的实现检查当前线程是否为主线程。如果是,则直接执行该方法。

ReceiveNotification 中不需要锁定,因为对 GetSomeStringFunction 的调用始终在主线程上执行。

关于multithreading - 我可以将 Delphi TThread.Synchronize() 本地移动到 VCL 表单以从主线程或工作线程调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42269432/

相关文章:

c# - async/await 如何帮助 ASP.Net 应用程序?

wpf - "The calling thread must be STA"解决方法

c# - 如何创建一个不会减慢 PC 速度的永无止境的线程

delphi - libvlc vmem 访问冲突

c# - 如何使非线程安全的第三方库实际上是线程安全的?

java - 意外的并发修改异常

c# - 为什么我的代码不能正常同步工作?

linux - 如何获取线程休眠的原因

delphi - 在图表上设置左轴以将十进制值增加到0.13?

delphi - Vcl.打印机.pas(888) : W1025 Unsupported language feature: 'custom attribute'