Ich lese Nick Hodges online und ich habe die Warteschlange entdeckt, aber es verhält sich nicht so, wie ich es erwartet habe und ich konnte nicht verstehen, was er und die Dokumentation sagen. Schau dir diesen Code an:
%Vor% Ich benutze immer Synchronize
, aber dieses Mal habe ich versucht mit Queue
, denn laut Nick ist es besser im Falle von Mehrfachanfragen, da sie nicht "serialisiert" und nacheinander ausgeführt werden. Der obige Code funktioniert einwandfrei. Warum funktioniert das nicht stattdessen?
In diesem Fall gibt das Memo start
aus, aber nicht das Ende. Wenn ich anrufe:
start
im Memo Der Unterschied zwischen Warteschlange und Synchronisierung besteht darin, dass Synchronize()
den Wert " ruft eine Warteschlange auf und wartet darauf, dass dieser Anruf abgeschlossen wird, und Queue()
Versetzt den Anruf in die Warteschlange und gibt die Steuerung direkt an den Thread zurück.
Allerdings ... und das wird nicht erwähnt in der offiziellen Dokumentation, wenn ein Thread fertig ist, alle Anrufe in der Warteschlange mit Queue(AThread, AMethod)
, wobei AThread das eigene
Das sieht man deutlich in der Quelle von TThread.Destroy()
wo RemoveQueuedEvents(Self)
heißt.
RemoveQueuedEvents entfernt in der Warteschlange befindliche Methodenaufrufe. [...] Wenn AThread angegeben wird, werden alle von diesem Thread in die Warteschlange gestellten Methodenaufrufe entfernt.
Also direkt nach dem letzten Queue()
endet Ihr Thread, TThread.Destroy()
wird ausgeführt und der / die letzte (n) Anruf (e) wird / werden aus der Warteschlange entfernt.
Es gibt einige Dinge, die Sie tun können, um dies zu lösen.
TThread.Queue(nil, AMethod)
aufrufen. B.T.W. Der Aufruf von TThread.Queue(AMethod)
ist identisch mit TThread.Queue(Self, AMethod)
, so dass Sie immer die nil-Variante verwenden müssen, wenn der Thread endet und Sie möchten, dass der Aufruf beendet wird. Synchronize()
als letzte Queue-Methode verwenden. Beachten Sie, dass die letzte Synchronisierung keine echte Prozedur sein muss. Sie können einfach am Ende des TThread.Execute
like Synchronize(DummySync)
( Beispiels ) eine Dummy-Prozedur aufrufen. Die Warteschlange, wenn FIFO so der Thread wird warten, bis alle Anrufe in der Warteschlange verarbeitet werden (einschließlich der leeren Dummysync). Einige zusätzliche Informationen finden Sie auf diesen Seiten. Stellen Sie sicher, dass alle TThread.Queue-Methoden abgeschlossen sind, bevor der Thread sich selbst zerstört
Ссылка
Tags und Links multithreading delphi