views:

314

answers:

2

It makes me confused when I read the article by Zarko Gajic today:

"Multithreaded Delphi Database Queries"

Article URL: http://delphi.about.com/od/kbthread/a/query_threading.htm

Sourecode: http://delphi.about.com/library/weekly/code/adothreading.zip

With the code of "TCalcThread.Execute" procedure, Why the following code do not need to be placed in the Synchronize() method to run?

Line 173:    ListBox.Clear;  
Line 179:    ListBox.Items.Insert(......);
Line 188:    ListBox.Items.Add('*---------*');
Line 195:    TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks);

These codes are operating the VCL components, and are related to the UI updates. In my knowledge, these operations should be use thread synchronize, and executed by the main thread. Is my knowledge has the flaw?

A: 

Indeed. Maybe the sample isn't problematic cause there are no UI changes while the thread is executing. But UI things always have to occur inside the UI thread.

The only differences I see between the sync'ed and the not sync'ed instructions are:

  • the not sync'ed are not no-params methods so the program will be more dificult to write :)
  • the sync'ed method is updating a TLabel which is not a TControl (if I remember my Delphi days) so it uses canvas directly...

But anyway: UI is touched by a single thread. Always. Once I wanted to update a TTreeBox inside a thread (no paralelism nor cross updates, simply a separate thread) and it was a very bad thing (random errors)...

helios
+17  A: 

This is a rare case where you're benefiting from the fact that Windows is doing the thread synchronization for you. The reason is that for a listbox, the items are manipulated using SendMessage with control specific messages. Because of this, each SendMessage call makes sure the message is processed by the same thread on which the control was created, notably the main thread.

Like I said, this is a rare case. It is also causing a thread switch for each of those three calls, which will degrade performance. You're still better off using Synchronize to force that block of code to run in the main thread where it belongs. It also ensures that if you begin working with a control that doesn't internally use SendMessage, you won't get bitten.

Allen Bauer