AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Arbeiten mit TThreadList

Ein Thema von Captnemo · begonnen am 7. Aug 2013 · letzter Beitrag vom 25. Jun 2014
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.190 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 14:51
Das ist die TThreadList aus System.Classes oder System.Generics.Collections , oder? Ich kann der nichts abgewinnen: Da fehlen elementarste Dinge wie ein GetEnumerator() und alles. Bist du sicher, dass du die brauchst? Ich hätte gedacht, dass du die RS232-Threads alle im Hauptthread erstellst und an die Liste dranhängst und ebenso dort auch die Liste wieder zumachen willst?

Ich nehme da einfach eine ganz "normale" Objektliste (TObjectList )- Soweit die OwnsObjects = True hat, ist die Freigabe der Liste mitsamt aller enthaltenen Threads so einfach wie ein meineListe.Free(); Bsp:
Delphi-Quellcode:
program Project4;

{$APPTYPE CONSOLE}
{$R *.res}

uses
   System.SysUtils,
   System.SyncObjs,
   System.Classes,
   System.Generics.Collections;

const
   numThreads: Integer = 5;

var
   threadList: TObjectList<TThread>;
   threadNum: Integer;
   threadIterator: TThread;
   consoleCs: TSynchroObject;

//{$DEFINE OWNSOBJECTS}

procedure writeConsole(const line: String);
begin
   consoleCs.Acquire();
   try
      WriteLn(line);
   finally
      consoleCs.Release();
   end;
end;

function constructRunningThread(const threadNum: Integer): TThread;
begin
   Result := TThread.CreateAnonymousThread(
      procedure
      begin
         writeConsole('Thread ' + threadNum.ToString() + ' startet...');
         sleep(1000 + Random(4000));
         writeConsole('Thread ' + threadNum.ToString() + ' endet...');
      end
   );
   Result.FreeOnTerminate := {$IFDEF OWNSOBJECTS}False{$ELSE}True{$ENDIF};
   Result.Start();
end;

begin
   try
      consoleCs := TCriticalSection.Create();

      writeConsole('Erstelle und fülle Liste...');
      threadList := TObjectList<TThread>.Create(
         {$IFDEF OWNSOBJECTS}True{$ELSE}False{$ENDIF}
      );
      for threadNum := 0 to Pred(numThreads) do
         threadList.Add(constructRunningThread(threadNum));

      writeConsole('Baue Liste ab...');
      threadList.Destroy();
      writeConsole('Liste abgebaut');
      writeConsole('<Taste drücken>');
   except
      on E: Exception do
         WriteLn(E.ClassName, ': ', E.Message);
   end;

   ReadLn;
end.


// Roter Kasten:
Entweder ein TThread hat FreeOnTerminate = True und du fasst ihn nach dem Starten nicht mehr an(!) oder er hat es auf False und du gibst die TThread-Instanz selbst so frei wie du möchtest. Ich habe das mal versucht in das Beispiel zu packen: Du kannst das {$DEFINE OWNSOBJECTS} einmal auskommentieren und dir den Unterschied anschauen
  Mit Zitat antworten Zitat
pertzschc

Registriert seit: 29. Jul 2005
Ort: Leipzig
311 Beiträge
 
Delphi 12 Athens
 
#2

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 15:48
Ich habe das mal versucht in das Beispiel zu packen
Mit welchem Delphi läuft Dein Code? Bei mir im Delphi 2010 geht z.B. das TThread.CreateAnonymousThread nicht.

Danke für einen Hinweis,
Christoph
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.190 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 18:35
Ich habe das mal versucht in das Beispiel zu packen
Mit welchem Delphi läuft Dein Code? Bei mir im Delphi 2010 geht z.B. das TThread.CreateAnonymousThread nicht.
Das war XE5 oder XE6, weiß ich nicht mehr.
Vielleicht kam das erst mit XE?
Aber ansonsten wäre es kein Unterschied, stattdessen mit (weitaus mehr Tippaufwand) sich auf klassischem Wege wieder eine Klasse TMyThread = class(TThread) zu definieren, Execute() zu implementieren und den letztendlich zurückzugeben.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 20:01
Ich verstehe gar nicht, was dieses Gehampel mit den Threads soll.
  1. Ein Thread sollte sich bei Delphi-Referenz durchsuchenTThread.Terminate von selber auch sauber beenden (muss nicht schlagartig sein, aber er sollte sich ab jetzt nur noch Augen für das Sandmännchen haben)
  2. Delphi-Referenz durchsuchenTThread.FreeOnTerminate - habe ich mal benutzt, ist aber ewig her, weil es mehr Probleme schafft als wirklich hilft
Solche Threads packt man einfach in eine ganz normale TObjectList (ja, OwnsObjects auf True) und wenn diese Threads aus dem Speicher sollen, dann ein ganz lapidares freigeben der Liste.

Ein Thread ruft im Destroy ganz von alleine das Delphi-Referenz durchsuchenTThread.Terminate auf, dann ein TThread.WaitFor .

Fazit: Die Thread-Klasse sauber aufbauen, dann klappt das wie von selber
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Arbeiten mit TThreadList

  Alt 25. Jun 2014, 11:42
Ein Thread ruft im Destroy ganz von alleine das Delphi-Referenz durchsuchenTThread.Terminate auf, dann ein TThread.WaitFor .

Fazit: Die Thread-Klasse sauber aufbauen, dann klappt das wie von selber
Na ja. Ich hatte immer Probleme (vielleicht älteres Delphi), einen Thread einfach so freizugeben. Erst seitdem ich Terminate,WaitFor,Free aufrufe, klappt es. Vielleicht ist das ja auch Aberglaube.
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Arbeiten mit TThreadList

  Alt 25. Jun 2014, 11:55
Apropos WaitFor. Darf ich mich mal kurz einklinken? Kann man das auch in den destructor schreiben oder ist es da schon zu spät?
Delphi-Quellcode:
constructor TFindSnapPointsThread.Create(List: TGraphicList);
begin
  inherited Create(true);
  FreeOnTerminate := true;
  FFindSnapPoints := TFindSnapPoints.Create;
  FList := List
end;

destructor TFindSnapPointsThread.Destroy;
begin
  WaitFor;
  FFindSnapPoints.Free;
  inherited Destroy;
end;

procedure TFindSnapPointsThread.Terminate;
begin
  FFindSnapPoints.Cancel := true;
  inherited Terminate;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Arbeiten mit TThreadList

  Alt 25. Jun 2014, 18:50
Es sollte reichen, wenn du die Instanzen nach dem inherited freigibst.
Delphi-Quellcode:
destructor TFindSnapPointsThread.Destroy;
begin

  inherited;
  FFindSnapPoints.Free;
end;
Um hier aber etwas wirklich konkretes zu sagen, musst du dir dringend einmal anschauen, was in TThread.Destroy so passiert.

In den neueren Delphi-Versionen wird dort eben genau das alles gemacht (Terminate ,WaitFor ,...).

Ein Thread ruft im Destroy ganz von alleine das Delphi-Referenz durchsuchenTThread.Terminate auf, dann ein TThread.WaitFor .

Fazit: Die Thread-Klasse sauber aufbauen, dann klappt das wie von selber
Na ja. Ich hatte immer Probleme (vielleicht älteres Delphi), einen Thread einfach so freizugeben. Erst seitdem ich Terminate,WaitFor,Free aufrufe, klappt es. Vielleicht ist das ja auch Aberglaube.
Das ist bei Delphi 7 wohl noch so, sollte aber auch durch einen Blick in TThread.Destroy zu klären sein, ob das wirklich nötig ist, oder ob es einfach reicht, den echten Destructor abzuwarten und dann erst alles einzureißen (s.o.)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:21 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 by Thomas Breitkreuz