Bei mir schauts dann so aus:
Delphi-Quellcode:
procedure TMainForm.Thread_UDP_ReceiveString(var Text: String);
begin
Text := '';
System.TMonitor.Enter(ClientThread);
try
If idUDPClient.Connected then
Text := IdUDPClient.ReceiveString(-1, TEncoding.UTF8);
finally
System.TMonitor.Exit(ClientThread);
end;
end;
Dann führst du das ReceiveString aber auch innerhalb des Locks aus, obwohl es dafür gar keinen Grund gibt. Besser ist es, wenn du alles fertig machst und dann nur noch in dem abgesicherten Teil die Zielvariable schreibst.
Denn je länger du Threads blockierst, desto eher übersiehst du mögliche Deadlocks, sprich dass sich zwei Threads gegenseitig blockieren, weil beide auf den anderen warten (z.B. einer im TMonitor.Enter, der andere in einem Synchronize, jetzt nur als Beispiel). Die Gefahr besteht hier nicht, aber trotzdem sollte man in einem Lock, sprich hier zwischen Enter und Exit, so wenig Code wie möglich ausführen.
Ich hänge mich mal hier mit dran. Normalerweise synchronisiere ich mit einer
Mutex oder einer CriticalSection.
Was sind da die Unterschiede? Beim TMonitor brauch ich wohl keine globale variable für die
Mutex oder?
TMonitor funktioniert über eine Objektreferenz. Auf die brauchst du also auch Zugriff. Innerhalb eines Objekts geht das mit Self sehr einfach.
Eine TCriticalSection ist tendentiell etwas schneller, ein
Mutex sehr viel langsamer, da dieser über den Kernel läuft. Einen
Mutex sollte man nur zur Interprozesskommunikation nutzen, nicht innerhalb eines Prozesses.
Wenn es um beste Performance geht, ist eine TCriticalSection meistens am besten. Wenn du das bisher so machst, ist das völlig in Ordnung. TMonitor ist aber einfacher zu nutzen, wenn man im Kontext eines Objekts ist, weshalb ich das trotzdem gerne nutze. Bei den meisten Anwendungsfällen wird der Performanceunterschied keine Rolle spielen.