Das Problem ist, wie Kamil bereits beschrieben hat, dass
ReadLn geblockt ist, also die "Programmzeile so lange wartet bis tatsächlich ein String ankommt". Mit
Syncronize wechselst Du in den Haupthread, so dass die Idee des Threads, nämlich diese Wartezeit unabhäng vom Hauptthread zu verbringen, untergraben wird...
Bei meiner exemplarischen Darstellung habe ich diesen Effekt durch eine fiktive Methode/Eigenschaft
HasData kompensiert, die solange
False zurückgibt, bis tatsächlich Daten vorhanden sind, so dass
ReadLn niemals warten würde.
Die Schleife
Delphi-Quellcode:
while not Terminated do
if FClient.HasData then
Synchronize(UpdateMemo)
else
Sleep(100);
entspricht demnach im Wesentlichen einem Polling (tatsächlich nicht wirklich elegant).
Um das Ganze in den Griff zu bekommen, solltest Du innerhalb von
Execute eine Exemplar-Variable mit dem Ergebnis von
ReadLn füllen und erst anschließend
Synchronize aufrufen, also in etwa so
Delphi-Quellcode:
while not Terminated do
begin
FReceivedString:= FClient.ReadLn;
Synchronize(UpdateMemo);
end;
Beachte, dass Du innerhalb von
UpdateMemo diese Exemplarvariable anstatt
FClient verwendest!
Nachteil dieses Ansatzes ist die Tatsache, dass
ReadLn per default "unendlich lange" wartet, Du also keine saubere Möglichkeit hast, den Thread zu beenden. Hier könnte ggf doch eine Variante des Pollings verwendet werden, damit zyklisch
Terminated abgefragt wird...