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

I am using CreateAnonymousThread for a work task, and when I started with it, I used Sync throughout the declaration as per the documented examples, for example:

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 can see, from within this thread, I fire event notifications to various parts of my application, including VCL forms (NotifyBeforeWorkerStuff, etc.). I later saw that I could move Synchronize () locally to each VCL form close to the point that actually required it to update (unsafe) VCL controls:

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

      

The workflow then becomes easier if I live with notifications from the main or workflow:

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

         NotifyBeforeWorkerStuff; 

         // Do worker stuff

         NotifyAfterWorkerStuff;

       end);

     FExecutionThread.Start;
   end;

      

I have a couple of questions about whether this is correct:

  • My notifications can be from the workflow, but also from the main thread (based on a button click, for example). So when the "ReceiveNotification" on the VCL form is called from the main thread, is it allowed to call TThread.Synchronize as above? The XE8 docs imply not, but the System.Classes check looks ok and it works fine.
  • Inside 'ReceiveNotification', when Label1.Caption retrieves a string from GetSomeStringFunction, is it correct that there is absolutely no need to block inside that function even when the call is from a worker thread?

Thanks for any advice.

+3


source to share


1 answer


The documentation says:

Warning: Do not call Sync from the main thread. This can cause an endless loop.



I think the documentation is simply wrong. The XE8 implementation checks if the current thread is the main thread. If so, then the method is executed directly.

No blocking is required ReceiveNotification

because the call is GetSomeStringFunction

always done on the main thread.

+4


source







All Articles