7

Stealing from Uwe Raabe's article Synchronize and Queue with Parameters I do this:

if GetCurrentThreadID = MainThreadID then
  FDataLogger(IntToStr(lNrItems) + ' elements:')
else
  TThread.Synchronize(nil,
          procedure
          begin
            FDataLogger(IntToStr(lNrItems) + ' elements:');
          end);

But if I just

  TThread.Synchronize(nil,
          procedure
          begin
            FDataLogger(IntToStr(lNrItems) + ' elements:');
          end);

that seems to work as well.

Since the first construct leads to more code, is there really much benefit from distinguishing the main thread?

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
  • By the way, the above code likely contains a different bug. If `lNrItems = 1`, it says "1 elements", which is grammatically wrong. The simplest (and arguably best) solution is to write `element(s)` in the string literals. – Andreas Rejbrand Mar 18 '20 at 11:39
  • 1
    @AndreasRejbrand It's just debugging logs ;-) – Jan Doggen Mar 18 '20 at 12:09

1 Answers1

5

Although the documentation warns you to do that, the actual code inside TThread.Synchronize resembles the wrapping code shown. So I am pretty sure that you can get away with the shorter version.

Perhaps I was also mislead by the documentation (or in ancient times may have been bitten by such a behavior in Delphi 5 or so) when I wrote that article.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • 2
    Well, the actual implementation is arguably irrelevant. If the documentation says that the method must not be used in the main thread, you arguably mustn't use it in the main thread. Even if you get away with that today, Embarcadero are free to change the implementation in the future, since they can assume that all decent developers follow the contract given by the documentation. Only if Embarcadero would change the documentation to allow this would it be safe to do so, because then Embarcadero promises that it is safe and that it will remain so. – Andreas Rejbrand Mar 18 '20 at 11:55
  • @AndreasRejbrand, I see your point and of course you are right. It is just that inspecting the code for a couple of Delphi versions back to Delphi 7 showed that it should be safe to do so. It was only in Delphi 5 which acts according to the documentation (I cannot tell for Delphi 6 in the moment). I would be pretty surprised when Embarcadero (or whoever will be in charge then) starts reverting the current behavior to something from the Delphi stone age. – Uwe Raabe Mar 18 '20 at 12:16
  • @UweRaabe even in Delphi 5 and earlier (the implementation was changed in Delphi 6), calling `Synchronize()` in the main thread was still safe. Synchronization was handled by Windows itself, not the RTL, but it was still thread-aware and would just execute the user procedure directly if called in the main thread. – Remy Lebeau Mar 18 '20 at 18:58