![]() |
Thread: Suspend und Resume deprecated
hallo,
ich beschäftige mich schon länger mit threads. jedoch habe ich eine wichtige frage: wenn ich einen thread starte und danach pausiere, mache ich das per suspend. das ist aber deprecated. was nutze ich alternativ: noch wichtiger: ich erwecke ihn nachher wieder mit resume. das ist aber auch deprecated. es wird empfohlen, stattdessen start zu nehmen. aber wenn ein thread bereits gestartet wurde unc ich nach suspend > start verwende, bekomme ich eine AV. ich kann einen gestartetetn thread nicht erneut starten, das ist das problem. was ist die funktionierende alternative zu resume? |
AW: Thread: Suspend und Resume deprecated
Das macht man eben nicht! :warn:
Genau deswegen ist Suspend auch endlich deprecated. Denn von außerhalb kann man nicht sicherestellen, daß der Thread in einem "sicheren" Zustand angehalten wird. Das kannst du maximal von innerhalb des Threads sicherstellen, indem er sich selber anhält, an einer definierten Stelle, oder wenn er von Anfang an Suspend ist (Parameter im Constructor). |
AW: Thread: Suspend und Resume deprecated
Zitat:
also ich nutze dazu immer eine Variable, die eben in Execute abgefragt und "von außen" gesetzt wird
Delphi-Quellcode:
nach bestem Wissen und Gewissen, aber ohne IDE aus dem Kopf runtergeschrieben
type TMyThread = class(TThread)
private FSleep : Boolean; FTerminated : Boolean; public procedure Execute; override; procedure GoToSleep; procedure WakeUp; end; procedure TMyThread.Execute; begin while not (FTerminated) do begin if not (FSleep) do begin //Befehle abarbeiten end else Sleep(10); end; end; procedure TMyThread.GoToSleep; begin FSleep := True; end; procedure TMyThread.WakeUp; begin FSleep := False; end; OK, das ist ein klein wenig anders, als den Thread wirklich "stillzulegen", aber wenn ich mich richtig erinnere, dann wurde dieses Verfahren auch hier schon empfohlen edit2: richtig, hier war's gewesen ![]() edit: Huch, der rote Kasten war zwar da, aber meine Meinung will ich Euch trotzdem nicht vorenthalten |
AW: Thread: Suspend und Resume deprecated
Eine alternative Lösung für das Suuspend / Resume Problem ist in den Indy Komponenten in der Unit IdThread enthalten.
Sie enthält eine Threadklasse (TIdThread), deren Execute Methode in einer Schleife liegt und deren Ausführung man von aussen leicht anhalten und wieder aufnehmen kann. TIdThread hat kaum externe Abhängigkeiten und kann daher auch leicht modifiziert ohne Indy verwendet werden. Funktioniert ab Delphi 5, ich selber nutze sie auch mit Delphi 6 und bisher problemlos. |
AW: Thread: Suspend und Resume deprecated
In meinem aktuellen Projekt mache ich das über ein Event.
Delphi-Quellcode:
type
TMyThread = class(TThread) private FEvent: THandle; ... public procedure SuspendWork; procedure ContinueWork; ... end; constructor TMyThread.Create; begin (* Non-Signaled-Event anlegen *) FEvent := CreateEvent(nil, true, false, ''); ... end; procedure TMyThread.ContinueWork; begin (* Event auf Non-Signaled zurücksetzen *) ResetEvent(FEvent); end; procedure TMyThread.Execute; begin ... (* Falls Event Signaled ist, warten *) while (WaitForSingleObject(FEvent, 0) = WAIT_OBJECT_0) and not Terminated do sleep(0); if Terminated then break; ... end; procedure TMyThread.SuspendWork; begin (* Event auf Signaled setzen *) SetEvent(FEvent); end; |
AW: Thread: Suspend und Resume deprecated
Zitat:
Unter ![]() |
AW: Thread: Suspend und Resume deprecated
Rate mal, wofür man dort ein TimeOut angeben kann.
WaitFor wartet auf das Event und will man nebenbei noch Eventunabhängig z.B. noch das Terminated prüfen, dann ginge das darüber. Über das TimeOut hat man quasi ein Sleep, welches regelmäßige Auswertungen erlaubt, den Thread meistens schlafen läßt (CPU-Entlastung) und gleichzeitig dennoch, über das Event, schnell reagieren kann. Siehe ![]() |
AW: Thread: Suspend und Resume deprecated
Klar geht das eleganter:
Delphi-Quellcode:
type
TMyThread = class(TThread) private FEvent: THandle; ... public destructor Destroy; override; procedure Terminate; override; procedure SuspendWork; procedure ContinueWork; ... end; procedure TMyThread.Terminate; begin inherited; SetEvent( FEvent ); end; destructor TMyThread.Destroy; begin if not Terminated then begin Terminate; WaitFor; end; inherited; end; constructor TMyThread.Create; begin (* Signaled-Event anlegen *) FEvent := CreateEvent(nil, true, true, ''); ... end; procedure TMyThread.ContinueWork; begin (* Event auf Signaled setzen *) SetEvent(FEvent); end; procedure TMyThread.Execute; begin while not Terminated do begin (* Falls Event Non-Signaled ist, warten *) if ( WaitForSingleObject( FEvent, INFINITE ) = WAIT_OBJECT_0 ) and not Terminated then begin // Hier jetzt das rein, was der Thread abarbeiten soll end; end; end; procedure TMyThread.SuspendWork; begin (* Event auf Non-Signaled setzen *) ResetEvent(FEvent); end; |
AW: Thread: Suspend und Resume deprecated
WaitForSingleObject kehrt auch zurück, wenn man das Handle mit CloseHandle schließt, d.h. man muss nicht unbedingt Terminate überschreiben.
Das geht nebenbei bei älteren Delphi-Versionen gar nicht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz