Mit synchronize funktioniert das ja, aber in verschiedenen Tutorials habe ich gelesen, dass man das nicht machen würde. Das wäre ja pro Schleifendurchlauf im Thread ein Aufruf von synchronize, der jedesmal den Thread kurz unterbrechen würde.
Neuere Delphi Versionen enthalten die Methode TThread.Queue, die im Unterschied zu Synchronize den Thread nicht sofort blockiert (sondern erst zu einem späteren Zeitpunkt). Queue legt den eigenen Methodenaufruf in eine Warteschlange und gibt die Kontrolle sofort an den Thread zurück. Im Haupthread wird dann "später" diese Queue abgearbeitet. Eine Garantie dafür gibt es aber nicht, z.B. falls beim Beenden des Programms noch Einträge in dieser Queue sind.