我可以将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?

查看:2020
本文介绍了我可以将Delphi TThread.Synchronize()本地移动到要从主线程或工作线程调用的VCL表单吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CreateAnonymousThread作为工作任务,当我开始使用它时,我在整个声明中使用了Synchronize,例如:

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, e.g:

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控件的点:

As you see, from within this thread I launch event notifications to various parts of my app including VCL forms (NotifyBeforeWorkerStuff etc). 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:

    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. 我的通知可能来自工作线程,但也可以来自主线程(例如派生自按钮按钮)。那么当从主线程调用VCL表单上的ReceiveNotification时,是否允许像上面那样调用TThread.Synchronize? XE8文档暗示不是,而是检查系统。类别看起来很好,它的工作正常。

  2. 当Label1.Caption从GetSomeStringFunction中获取字符串时,在ReceiveNotification内部,是否正确的是,即使在该函数中绝对不需要锁定来电来自工作线程?

  1. My notifications may be from the worker thread but also from the main thread (e.g 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? The the XE8 docs imply not, but checking System.Classes this looks ok and it works fine.
  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?

感谢任何建议。

推荐答案

文档说:


警告:不要调用同步从主线程内。这可能导致无限循环。

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

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

I think that documentation is simply wrong. The implementation in XE8 checks whether or not the current thread is the main thread. If it is then the method is executed directly.

ReceiveNotification 不需要锁定,因为调用 GetSomeStringFunction 总是在主线程上执行。

No locking is required in ReceiveNotification because the call to GetSomeStringFunction is always performed on the main thread.

这篇关于我可以将Delphi TThread.Synchronize()本地移动到要从主线程或工作线程调用的VCL表单吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆