Diese Frage bezieht sich auf Delphi und XE, die Suspend and Resume explizit ablehnen. Ich habe andere Beiträge gelesen und ich habe bisher keine ähnliche Verwendung gefunden, also werde ich weitermachen und nach einer Diskussion fragen.Selbstaussetzung eines Threads in Delphi, wenn dieser nicht benötigt wird und sicher fortgesetzt wird
Was ich gerne wissen würde, gibt es eine bessere Möglichkeit, einen Thread anzuhalten, wenn es nicht benötigt wird?
Wir haben eine Delphi-Klasse, die wir seit Jahren verwenden, die im Grunde eine FIFO-Warteschlange ist, die einem Thread-Prozess zugeordnet ist. Die Warteschlange akzeptiert ein Datenobjekt im Haupt-Thread und wenn der Thread ausgesetzt wird, wird er fortgesetzt.
Als Teil des Execute-Prozesses des Threads wird das Objekt aus der Warteschlange herausgeholt und im Thread verarbeitet. Normalerweise ist dies eine Datenbanksuche.
Am Ende des Prozesses wird eine Eigenschaft des Objekts aktualisiert und als für den Hauptthread verfügbar markiert oder an eine andere Warteschlange übergeben. Der letzte Schritt des Execute-Prozesses besteht darin, zu prüfen, ob weitere Elemente in der Warteschlange vorhanden sind. Wenn es weiter geht, setzt es sich sonst aus.
Der Schlüssel ist die einzige Suspend-Aktion innerhalb der Execute-Schleife, wenn sie abgeschlossen ist, und die einzige Fortsetzung während des normalen Betriebs wird aufgerufen, wenn ein neues Element in die Warteschlange gestellt wird. Die Ausnahme ist, wenn die Queue-Klasse beendet wird.
Die Lebenslauffunktion sieht ungefähr so aus.
process TthrdQueue.MyResume();
begin
if Suspended then begin
Sleep(1); //Allow thread to suspend if it is in the process of suspending
Resume();
end;
end;
Das sieht auf diese
process TthrdQueue.Execute();
var
Obj : TMyObject;
begin
inherited;
FreeOnTerminate := true;
while not terminated do begin
if not Queue.Empty then begin
Obj := Pop();
MyProcess(Obj); //Do work
Obj.Ready := true;
end
else
Suspend(); // No more Work
end; //Queue clean up in Destructor
end;
Die TthrdQueue Routine Anrufe nach dem Hinzufügen ein anderes Objekt in dem Stapel MyResume Drücken ähnlich auszuführen. MyResume ruft Resume nur dann auf, wenn der Thread gesperrt ist.
Beim Herunterfahren setzen wir terminate auf true und rufen MyResume auf, wenn es angehalten ist.
Ich bin kein Experte, aber ich würde einfach Sleep (250) oder SignalObjectAndWait (siehe msdn) für eine genauere Kontrolle verwenden. –