Selbst die Aussetzung eines Threads in Delphi, wenn es nicht benötigt wird und sicher fortsetzen
Diese Frage beinhaltet und Delphi XE-insbesondere der veralteten Anhalten und Fortsetzen. Ich habe andere Beiträge gelesen, und ich habe nicht gefunden, eine ähnliche Nutzungs-so weit, so werde ich gehen Sie vor und stellen Sie zur Diskussion stellen.
Was ich wissen möchte ist gibt es einen besseren Weg, um pause ein thread, wenn es nicht benötigt wird?
Haben wir eine Delphi-Klasse, wir haben seit Jahren verwendet, das ist im Grunde eine FIFO-Warteschlange, die mit einem Gewinde-Prozess. Die Warteschlange nimmt eine Daten-Objekt auf dem Haupt-thread und wenn der thread unterbrochen wird, wird es fortsetzen.
Als Teil des thread Ausführen des Prozesses das Objekt tauchte aus der queue und verarbeitet auf den thread. In der Regel ist also eine Datenbank-lookup.
Am Ende des Prozesses eine Eigenschaft des Objekts wird aktualisiert und als verfügbar gekennzeichnet sind, bis der main-thread oder an eine andere Warteschlange. Der Letzte (gut, es ist wirklich der erste) Schritt der Execute-Prozess ist zu prüfen, ob es weitere Elemente in der Warteschlange. Wenn es so bleibt, sonst unterbricht sich selbst.
Diese Taste ist die einzige suspend-Aktion ist in der Execute-Schleife, wenn es fertig ist, und erst dann wieder aufgenommen, während des normalen Betriebs wird aufgerufen, wenn ein neues Element wird in die queue gestellt. Die Ausnahme ist, wenn der queue-Klasse wird beendet.
Die resume-Funktion 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;
Die Ausführung sieht ähnlich wie 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;
Den TthrdQueue Push-routine ruft MyResume nach dem hinzufügen von einem anderen Objekt im Stapel. MyResume nur Anrufe Fortzusetzen, wenn der thread unterbrochen wird.
Beim Herunterfahren setzen wir beenden auf true und rufen Sie MyResume, wenn es ausgesetzt ist.
- Ich bin kein Experte, aber ich würde einfach verwenden, Sleep(250) oder SignalObjectAndWait (siehe msdn) zur genaueren Kontrolle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich würde empfehlen, die folgende Implementierung von TthrdQueue:
Anstelle der Aussetzung der thread, damit es schlafen. Machen Sie es sperren auf einige wartemöglichkeit handhaben, und wenn der Griff wird signalisiert, wird der Faden aufwachen.
Haben Sie viele Möglichkeiten für wartemöglichkeit Objekte, events, mutex-Objekte, Semaphore, message queues, pipes.
Angenommen, Sie wählen eine Veranstaltung. Machen Sie es eine auto-reset-Ereignis. Wenn die Warteschlange leer ist, rufen Sie die Veranstaltung
WaitFor
Methode. Wenn etwas anderes füllt die Warteschlange oder aufhören will, haben es rufen Sie die VeranstaltungSetEvent
Methode.Ich bevorzugte Technik ist die Verwendung des OS-message-queue. Ich würde ersetzen Sie Ihre queue-Objekt mit Nachrichten. Dann schreiben Sie ein standard -
GetMessage
Schleife. Wenn die Warteschlange leer ist, wird es automatisch sperren, warten, bis eine neue Nachricht. Schalten Sie eine Kündigung auf Antrag in einer anderen Nachricht. (DieTThread.Terminate
Methode ist nicht einfach eine sehr nützliche Funktion, wenn Sie anfangen etwas zu tun interessant, mit Gewinde, weil es nicht virtual.)Gibt es eine Bibliothek erlaubt die Implementierung von Erzeuger-Verbraucher-queue in Delphi mit Bedingungs-Variablen. Dieses Szenario ist eigentlich das Beispiel diskutiert.