简体   繁体   English

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

[英]Can I move Delphi TThread.Synchronize() locally to a VCL form to be called from both a main or worker thread?

I am using CreateAnonymousThread for a worker task, and when I started with it I used Synchronize within the entire declaration as per documented examples, eg: 我正在使用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;

As you see, from within this thread I launch event notifications to various parts of my app including VCL forms (NotifyBeforeWorkerStuff etc). 如您所见,在此线程中,我向我的应用程序的各个部分启动事件通知,包括VCL表单(NotifyBeforeWorkerStuff等)。 Later, I saw that I could move Synchronize() more locally to each VCL form close to the point that actually required it for updating (non-safe) VCL controls: 后来,我看到我可以将Synchronize()更多地本地移动到每个VCL表单,接近实际需要它更新(非安全)VCL控件的点:

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

The worker thread then becomes simpler as long as I live with notifications being from either main or worker threads: 只要我接收来自主线程或工作线程的通知,工作线程就会变得更简单:

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

         NotifyBeforeWorkerStuff; 

         // Do worker stuff

         NotifyAfterWorkerStuff;

       end);

     FExecutionThread.Start;
   end;

I have several questions about whether this is correct: 关于这是否正确,我有几个问题:

  1. My notifications may be from the worker thread but also from the main thread (eg derived from a button press). 我的通知可能来自工作线程,也来自主线程(例如,从按下按钮导出)。 So, when 'ReceiveNotification' on a VCL form is called from the main thread, is it allowed to call TThread.Synchronize as above? 因此,当从主线程调用VCL表单上的“ReceiveNotification”时,是否允许如上所述调用TThread.Synchronize? The the XE8 docs imply not, but checking System.Classes this looks ok and it works fine. XE8文档意味着没有,但检查System.Classes这看起来没问题,它工作正常。
  2. Within 'ReceiveNotification' when Label1.Caption fetches the string from GetSomeStringFunction, is it correct that there is absolutely no need for locking within that function even when the call is from a worker thread? 当Label1.Caption从GetSomeStringFunction中获取字符串时,在“ReceiveNotification”内,是否正确,即使调用来自工作线程,也绝对不需要在该函数中进行锁定?

Thanks for any advice. 谢谢你的建议。

The documentation says: 文件说:

Warning: Do not call Synchronize from within the main thread. 警告:不要在主线程内调用Synchronize。 This can cause an infinite loop. 这可能导致无限循环。

I think that documentation is simply wrong. 我认为文档是完全错误的。 The implementation in XE8 checks whether or not the current thread is the main thread. XE8中的实现检查当前线程是否是主线程。 If it is then the method is executed directly. 如果是,则直接执行该方法。

No locking is required in ReceiveNotification because the call to GetSomeStringFunction is always performed on the main thread. 没有锁定是必需的ReceiveNotification因为呼叫GetSomeStringFunction总是在主线程上执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM