1

I have an old Delphi 7 project. When the application starts, a lot of dictionaries are loaded into the ComboBoxes.

Is it safe to fill ComboBoxes in a separate thread without the Synchronize method? During the loading process, the user does not yet have access to the visual components and will receive it only after all threads have finished.

Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159
  • 1
    It is NEVER safe to work with a GUI control from a separate thread without synchronizing. This question keeps getting asked over and over again, and the answer is always the same. – Ken White Dec 18 '20 at 21:49

1 Answers1

2

Is it safe to fill ComboBoxes in a separate thread without the Synchronize method?

No. It is never thread-safe to access GUI controls in background thread without synchronization.

Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159
  • 5
    Rather than having the thread fill the ComboBox directly, synchronizing each insertion, I would suggest having the thread fill in a local `TStringList` first, and then when done it can synchronize 1 time to assign the entire `TStringList` to the ComboBox in one operation. – Remy Lebeau Dec 18 '20 at 18:02
  • @Remy Lebeau I also did something like this (filling `TStringList` in Thread, and a single assignment in synchronization to `ComboBox.Items`) in the `OnCreate` event of the form, but the GUI does not draw properly until the thread ends. – yonni Nov 17 '22 at 14:53
  • @yonni GUI will draw itself, when the application is capable of processing Windows message queue. If Synchronize call is the last thing you do in a thread, this may look like GUI waited for thread to finish. Also if you are calling free on a thread from GUI thread that will cause GUI to wait for a thread to actually finish before it can continue with the message processing. It all depends on your exact code. – Dalija Prasnikar Nov 17 '22 at 15:11
  • @Dalija Prasnikar The code in the `Execute` procedure of the thread performs a loop `For var I: Integer := 1 to 6000 do SL.Add(MyFunc(I));` and then `Synchronize(procedure begin Combo.Items := SL; end)`. Why doesn't the GUI draw before the call to Synchronize? What is blocking it? – yonni Nov 17 '22 at 15:19
  • 1
    @yonni we can't answer that without seeing the rest of your GUI code, especially your `OnCreate` code. Feel free to post a separate question that provides a [mcve] demonstrating your issue. – Remy Lebeau Nov 17 '22 at 15:22
  • @yonni GUI does not draw before synchronize because you are not filling the items in combo box, you are adding the items to the string list. Only in Synchronize you are assigning that prefilled content to the GUI. – Dalija Prasnikar Nov 17 '22 at 15:22
  • @Dalija Prasnikar Obviously, all I need is for the form to display properly even before the combo is filled. I asked a new question (with code) https://stackoverflow.com/questions/74478358/filling-tcombobox-with-items-from-tstringlist-using-thread – yonni Nov 17 '22 at 15:53
  • @Remy Lebeau Please check out my new question here: https://stackoverflow.com/questions/74478358/filling-tcombobox-with-items-from-tstringlist-using-thread – yonni Nov 17 '22 at 15:54