Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Alle subThreads beenden beim programm beenden (https://www.delphipraxis.net/15476-alle-subthreads-beenden-beim-programm-beenden.html)

Meflin 29. Jan 2004 15:23


Alle subThreads beenden beim programm beenden
 
Hi,
gibt es eine komfortablere möglichkeit, alle threads einer anwendung zu beenden, als deren
handle beim starten zu sichern und dann in einer for - schleife zu beenden?

*MFG*

Luckie 29. Jan 2004 19:48

Re: Alle subThreads beenden beim programm beenden
 
Mit oder ohne VCL?

Egal wie sollte man es so programmieren, dass sich ein Thread selber beendet. Also im Thread in der Schleife einen Flag prüfen und wennd er einen bestimmten Wert hat die Schleife verlassen. Dieses Flag kannst du beim Programm Ende setzten.

trifid 29. Jan 2004 21:41

Re: Alle subThreads beenden beim programm beenden
 
aber die Threads gehören zu einem Prozess
wenn der Prozess gekillt wird, werden auch die Threads zum Prozess vom Betriebssystem terminiert
oder gibts da noch was zu beachten

Luckie 29. Jan 2004 23:13

Re: Alle subThreads beenden beim programm beenden
 
Saubere wäre es wohl, wenn sich die Threads alle vorher selber sauber beenden. Dass die Threads automatisch terminiert werden ist logisch. Wenn du den Prozess beendest, ziehst du ihnen ja praktisch den Teppich unter den Füßen weg. Ein Prozess ist nichts anderes als ein Container, der den Adressraum usw. bereitstellt.

Robert_G 29. Jan 2004 23:15

Re: Alle subThreads beenden beim programm beenden
 
Du könntest Probleme bekommen wenn dein Thread eine Datei schreibt oder liest...

APP 30. Jan 2004 04:04

Re: Alle subThreads beenden beim programm beenden
 
Hallo Trifid,

Zitat:

Zitat von trifid
aber die Threads gehören zu einem Prozess
wenn der Prozess gekillt wird, werden auch die Threads zum Prozess vom Betriebssystem terminiert
oder gibts da noch was zu beachten

bist Du Dir da sicher?
Ich habe das Zippen mit TP-Abbrevia in einen Thread ausgelagert, und meine, dass wenn ich beim Beenden des Prozesses nicht auf das Threadende warte bzw. ihn nicht vorsätzlich terminiere, dass dann der Thread weiterläuft, bzw. es zu "Seiteneffekten" (Exceptions) kommt...

trifid 30. Jan 2004 09:09

Re: Alle subThreads beenden beim programm beenden
 
@APP
Zitat:

bist Du Dir da sicher?
das was jetzt Luckie beschrieben hat und das was ich weiss ... JEIN
ein NEIN bei Verwendung mit dem Delphi-Objekt TThread
ein JA mit den API's (CreateThread, ...)
mit C,C++ hatte ich weniger Probleme als bei Delphi

Zitat:

Ich habe das Zippen mit TP-Abbrevia in einen Thread ausgelagert, und meine, dass wenn ich beim Beenden des Prozesses nicht auf das Threadende warte bzw. ihn nicht vorsätzlich terminiere, dass dann der Thread weiterläuft, bzw. es zu "Seiteneffekten" (Exceptions) kommt...
Abbrevia ist thread-sicher programmiert (TAbPadLock),
(was aber nicht heisst, dass die Threads sauber beendet werden können)
also dürfte es nur daran liegen was GeorgeWNewbie geschildert hat.
Ich habe mir angewöhnt immer an die entscheidenden Stellen ein WaitForSingleObject oder
WaitForMultipleObjects zu stellen. (z.B. beim FormClose)

Verwendest Du das TThread-Objekt - da ist bei Terminierung ein Bug enthalten

Luckie 30. Jan 2004 10:08

Re: Alle subThreads beenden beim programm beenden
 
@APP: Ein Thread ist ohne Prozess nicht lebensfähig! Da gibt es nichts dran zu rütteln. Aber wie geasgt, es könnte sein, dass es kracht, weil wenn du den Prozess beendest, dann nimmst du einen laufenden Thread seine Lebensgrundlage und manche finden das wohl nicht so toll und wehren sich vor ihrem Tod eben. ;)

APP 30. Jan 2004 10:10

Re: Alle subThreads beenden beim programm beenden
 
Hallo Trifid,

Zitat:

Zitat von trifid
Verwendest Du das TThread-Objekt (D5 u. D7) - da ist bei Terminierung ein Bug enthalten

ja, ich verwende das TThread-Objekt, kannst Du mir bitte sagen, wo der Bug ist?



@Trifid, @Luckie,

Ich habe obiges Posting "aus dem Bauch heraus" geschrieben, nachdem ich
um 2.00 Uhr früh in meine Fa. musste, und mir eine Wartezeit mit der DP verkürzte
-da war ich mir auch nicht sicher, ich beschrieb nur meine Erfahrungen
die ich mit Threads hatte.

Nun ließ mir das keine Ruhe und ich begann nachzulesen:

Andreas Kosch schreibt in "Delphi Win32 Lösungen" (Seite 298) folgendes:

Zitat:

Zitat von Delphi Win32 Lösungen
[..]Aus diesem Grund muss jedes Handle über den Aufruf von CloseHandle
so früh wie möglich freigegeben werden. Dabei bedeutet das Freigeben des Handles nicht,
dass auch das Threadobjekt zerstört wird. Solange der Thread seine Aufgaben
noch nicht erledigt hat, führt das Schließen des Handles nicht zum Freigeben des Threadobjektes.

[..]
Win32 schließt alle Objekthandle selbstständig, wenn der zugrundeliegende Prozess terminiert.

Wichtig ist in dem Fall, dass eine Freigabe des Handles nicht automatisch das Threadobjekt zerstört,
und zwar unabhängig davon ob der Thread mit dem TThread Objekt oder durch die WinAPI erzeugt wurde.

Luckie 30. Jan 2004 10:20

Re: Alle subThreads beenden beim programm beenden
 
Jupp, davon war aber gar nicht die Rede. Ein Thread-Handle kannst du sofort schließen, wenn du es nicht mehr brauchst. Mache ich in der Regel auch immer so, damit ich es nicht vergesse.

Ich benutze es meist nur, um zu kucken, ob alles geklappt hat:
Delphi-Quellcode:
    // Thread gleich starten
    hThread := BeginThread(nil, 0, @Thread, ThreadParams, 0, ThreadID);
    // wenn hThread <> 0 hat alles geklappt
    if hThread <> 0 then
    begin
      // nicht mehr benötigtes Thread-Handle schließen
      CloseHandle(hThread);
      // Schalflächen aktivieren / deaktivieren
      Button1.Enabled := False;
      Button2.Enabled := True;
    end;

Meflin 30. Jan 2004 17:45

Re: Alle subThreads beenden beim programm beenden
 
also, dateien werden bei dem ganzen nicht verwendet. normalerweise beenden sich die threads auch selber! das problem taucht nur auf, wenn der user wärend der threadlaufzeit das programm-schliesen-symbol drückt. wenn ich dann ein flag setzte, woher soll ich dann wissen, wie lange es dauert, bis alle threads beendet sind und die anwendung sauber beendet werden kann?

APP 30. Jan 2004 19:04

Re: Alle subThreads beenden beim programm beenden
 
Hallo Meflin,

Du könntest ja bei jedem Erzeugen eines Threads z.B. einen Zähler mitlaufen lassen,
und beim Beenden der Form nachschauen ob der Zähler > 0 ist:


Delphi-Quellcode:
...
TYPE
  TForm1 = CLASS(TForm)
    Button1: TButton;
    PROCEDURE FormCreate(Sender: TObject);
    PROCEDURE FormCloseQuery(Sender: TObject; VAR CanClose: Boolean);
    PROCEDURE Button1Click(Sender: TObject);
  PRIVATE
    FThreadCounter: Integer;
    PROCEDURE HandleTerminate(Sender: TObject);
  PUBLIC
  END;
VAR
  Form1                            : TForm1;

IMPLEMENTATION
{$R *.DFM}
Uses DeineThreadUnit;

VAR
  WorkerThread                    : TWorkerThread;

PROCEDURE TForm1.HandleTerminate(Sender: TObject);
// Behandlungsroutine, wenn Thread zerstört wird
BEGIN
  Dec(FThreadCounter);
END;

PROCEDURE TForm1.FormCreate(Sender: TObject);
BEGIN
  // Voreinstellung: 0 Threads aktiv
  FThreadCounter := 0;
END;

PROCEDURE TForm1.FormCloseQuery(Sender: TObject; VAR CanClose: Boolean);
// Form wird nur beendet, wenn kein Thread mehr aktiv ist
BEGIN
  CanClose := False;
  IF FThreadCounter > 0 THEN
    ShowMessage('Bitte Warten, Threads aktiv!')
  ELSE
    BEGIN
      IF Assigned(WorkerThread) THEN FreeAndNil(WorkerThread);
      CanClose := True;
    END;
END;

PROCEDURE TForm1.Button1Click(Sender: TObject);
// Viele, Viele Viele Threads erzeugen
BEGIN
  WorkerThread := TWorkerThread.Create(True);
    WITH WorkerThread DO
    BEGIN
      // Selbstzerstörung
      FreeOnTerminate := True;
      // ...
      // div. Übergaben an Properties des Threads
      // ...
      // Threadcounter erhöhen
      Inc(FThreadCounter);
      // Behandlungsroutine, wenn Thread zerstört wird
      OnTerminate := HandleTerminate;
      Resume;
    END;
END;

Meflin 31. Jan 2004 11:24

Re: Alle subThreads beenden beim programm beenden
 
also, da es scheinbar keine einfachere möglichkeit gibt, beende ich alle threads einzeln.
aber: neues problem! ich beende also alle nohc laufenden threads beim OnClose mit endthread (ich verwende nicht das vcl-thread object) und das fenster verschwindet, keine fehlermeldungen, alles paletti... doch: der prozess der application läuft noch!!! was geht denn da schief?

APP 31. Jan 2004 17:39

Re: Alle subThreads beenden beim programm beenden
 
Hallo Meflin,
Ich dachte nach Deinem letzten Posting, Du möchtest einfach nur warten,
bis sich alle Threads von selbst beendet haben und danach erst dem Anwender
erlauben das Fenster zu schließen.

Wenn Du aber alle offenen Threads auf einem Sitz beenden möchtest
würde ich bei VCL-Threads folgendes machen:

Delphi-Quellcode:
// Form1 Private
   FMyThreadList: TObjectList;

// Form1 create
   // False unterbindet das automatische Freigeben des Objekts in der Liste nach Delete.
   FMyThreadList:= TObjectList.create(False);

// Beim Erzeugen der Threads
   FMyThreadList.Add(WorkerThread);


PROCEDURE TForm1.HandleTerminate(Sender: TObject);
// Behandlungsroutine, wenn Thread zerstört wird
// Wenn sich ein Thread selbst beendet hat, muß die
// FMyThreadList aktualisiert werden.
VAR
  i                               : integer;
BEGIN
  FOR i := 0 TO FMyThreadList.Count - 1 DO
    IF Sender = FMyThreadList[i] THEN
      BEGIN
        FMyThreadList.Delete(i);
        Break;
      END;
END;

PROCEDURE TForm1.FormDestroy(Sender: TObject);
// Alle Threads killen, und warten bis sie fertig sind.
VAR
  i                               : integer;
BEGIN
  TRY
    FOR i := FMyThreadList.Count - 1 DOWNTO 0 DO
      BEGIN
        WITH TWorkerThread(FMyThreadList[i]) DO
          BEGIN
            // Verhindern, dass HandleTerminate aufgerufen wird
            OnTerminate := NIL;
            Terminate;
            WaitFor;
          END;
        FMyThreadList.Delete(i);
      END;
  FINALLY
    FMyThreadList.Free;
  END;
END;

Meflin 1. Feb 2004 09:59

Re: Alle subThreads beenden beim programm beenden
 
hmmm... ich verwende aber nicht den vcl thread -/-

*MFG*


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