4

I know that you need synchronize (yourprocedure) to set e.g. a label's text. But what about:

  1. Reading a label's text.
  2. Toggle/Set the label's enabled property.
  3. Call other labels procedures/functions (e.g. onclick event).

Is there an easy rule to know/remember when I need to use synchronize?

PS.: Is synchronize similar to PostMessage/SendMessage?

Ben
  • 3,380
  • 2
  • 44
  • 98

2 Answers2

10

Easy rule of thumb: ANY access to VCL UI components needs to be synchronized. That includes both reading and writing of UI control properties. Win32 UIs, most notably dialogs like MessageBox() and TaskDialog(), can be used directly in worker threads without synchronizing.

TThread.Synchronize() is similar to SendMessage() (in fact, it used to be implemented using SendMessage() internally in Delphi 5 and earlier). TThread.Queue() is similar to PostMessage().

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you very much. Then I really need to do a lot of procedures/functions to synchronize. – Ben May 15 '13 at 00:32
4

Any time you access a VCL UI component, you need to implement some type of thread safety measure. This is also, typically, the case when you're accessing a variable or procedure that exists or will be accessed by another thread. However, you don't need to use the Synchronize method in all of these situations. There are other tools at your disposal, and Synchronize is not always your best solution.

Synchronize blocks both the main thread and the calling thread while it's performing the procedure that you pass to it, so overusing it can detract from the benefits of multi-threading. Synchronize is probably most commonly used for updating your UI, but if you find that you're having to use it really frequently, then it might not be a bad idea to check and see if you can restructure your code. I.E. do you really need to read labels from within your thread? Can you read the label before starting the thread and pass it into the thread's constructor? Can you handle any of these tasks in the thread's OnTerminate event handler?

Aaron
  • 189
  • 6
  • Unfort. No. I need occasional checks while running the thread. I actually think that reading a value/property shouldn't be a problem as long as no other thread tries to set/write the address space. However it has to dealt with caution. – Ben May 15 '13 at 10:35
  • 1
    Your wording is unfortunate. The calling thread is certainly blocked, but the main thread certainly isn't - how could it execute the passed procedure if it were? – mghie May 15 '13 at 13:18
  • 1
    The main thread is blocked while it executes the passed procedure...as in, it doesn't respond to events or perform any other tasks. I believe that the meaning of my statement was fairly clear to anybody who wasn't reading it for the sake of finding a reason to discuss semantics. – Aaron May 15 '13 at 15:50