Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Wie schließe ich einen schlafenden Thread ? (https://www.delphipraxis.net/170840-wie-schliesse-ich-einen-schlafenden-thread.html)

MarLe 5. Okt 2012 10:07

Delphi-Version: XE2

Wie schließe ich einen schlafenden Thread ?
 
Hallo zusammen,

ich starte einen Thread mit Start und pausiere diesen mit Suspend.
Wenn ich diesen mit Terminate stoppen will bleibt mir der Thread aber erhalten (Taskmanager).
Vorher wieder mit Resume aufwecken und dann stoppen klappt.

Ist das die richtige Vorgehensweise ???

Gruß MarLe

(mir ist bekannt dass Suspend und Resume deprecated sind)

himitsu 5. Okt 2012 10:09

AW: Wie schließe ich einen schlafenden Thread ?
 
Man legt Threads eben nicht mit Suspend lahm. :warn:
Wenn du das nicht mehr machst, dann hat sich dieses Problem automatisch gelöst.

Der Thread befindet sich dadurch in einem unsicheren Zustand, er könnte sogar das ganze Programm lahmlegen, wenn man ihn z.B. anhält, wärend er grade was im MemoryManager erledigt und dadurch die Sperre nicht mehr freigegeben wird.
Und wenn man ihn nun auch noch "hart" abschießen würde, dann bleibt dieser Zustand für immer so, vorallem da der Thread dann nix mehr aufräumen kann, wofür er aber arbeiten müßte.


Fazit:
- du machst das nicht mehr und fertig ist
- oder du läßt den Thread weiterlaufen, sagst ihm "hör auf" und er beendet sich selber

MarLe 5. Okt 2012 11:31

AW: Wie schließe ich einen schlafenden Thread ?
 
... das weis ich ja dass man Suspend eigentlich nicht mehr verwenden soll.

Ich habe das Demo TThreadObject von Luckie durchgearbeitet (weil es meinen Anforderungen
ähnelt) und da tritt der Fall auf. Habe ansonsten zwar einiges gelesen und teilweise verstanden
wie man es machen soll, aber kein so schönes fertiges Beispiel zum Testen (und erweitern) gefunden.

Gruß MarLe

DeddyH 5. Okt 2012 12:46

AW: Wie schließe ich einen schlafenden Thread ?
 
Du könntest einen Event nutzen, siehe MSDN-Library durchsuchenCreateEvent, MSDN-Library durchsuchenSetEvent und MSDN-Library durchsuchenResetEvent.
Delphi-Quellcode:
constructor TDingsThread.Create;
begin
  FEvent := CreateEvent(nil, true, true, '');
  inherited;
end;

destructor TDingsThread.Destroy;
begin
  CloseHandle(FEvent);
  inherited;
end;
Im Execute des Threads wartest Du dann auf diesen Event.
Delphi-Quellcode:
while (WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0) and not Terminated do
Anhalten geht dann mit ResetEvent, Fortfahren mit SetEvent.
Delphi-Quellcode:
procedure TDingsThread.Pause;
begin
  ResetEvent(FEvent);
end;

procedure TDingsThread.ContinueWork;
begin
  SetEvent(FEvent);
end;
Wenn ich nichts Wesentliches vergessen habe, sollte das so funktionieren.

himitsu 5. Okt 2012 13:01

AW: Wie schließe ich einen schlafenden Thread ?
 
Man könnte sich noch vor und nach die Schlaf-Schleife eine Variable platzieren, über welche man extern abfragen kann, ob der Thread grade arbeitet.

z.B. ein LongBool (nach LongInt gecastet), welcher über MSDN-Library durchsuchenInterlockedExchange gesetzt wird. Und abfragen kann man ihn direkt, über ein ReadOnly-Property. (Lesezugriffe sind dort threadsave)

MarLe 11. Okt 2012 15:06

AW: Wie schließe ich einen schlafenden Thread ?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

Danke für die Tipps, habe jetzt mal versucht das Beispiel "quick and dirty" auf Events umzustellen.
Jetzt hängt sich das Ganze im Betrieb auf (keine Rückmeldung).
Beim Debuggen zählt er den Counter noch hoch, aber irgendwas stimmt mit der GUI Synchronisation scheinbar nicht.
Vielleicht hat Jemand Lust sich das mal anzuschauen.

(dass der Zugriff auf TListView nicht threadsicher ist weis ich, darauf werde ich mich anschließend stürzen)

Gruß MarLe

Björn Ole 11. Okt 2012 15:33

AW: Wie schließe ich einen schlafenden Thread ?
 
Nicht TThread.Execute manuell aufrufen, sondern TThread.Start benutzen. :wink:

DeddyH 11. Okt 2012 15:39

AW: Wie schließe ich einen schlafenden Thread ?
 
Bzw. TThread.Resume bei Delphi < 2009.

himitsu 11. Okt 2012 16:08

AW: Wie schließe ich einen schlafenden Thread ?
 
Zitat:

Nicht TThread.Execute manuell aufrufen
Darum ist Execute auch eigentlich als Protected deklariert (strict protected wäre aber besser), damit man eigentlich garnicht erst nicht auf die Idee kommen sollte, dieses von außen direkt aufrufen zu wollen. :angle2:

MarLe 12. Okt 2012 11:43

AW: Wie schließe ich einen schlafenden Thread ?
 
Aha, hab ich jetzt so umgesetzt, Danke.
Die Threads springen jetzt an, reagieren aber nicht auf Pause bzw. Stop.
Vielleicht kann noch mal Jemand eine Blick darauf werfen.

Gruß MarLe


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:40 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