![]() |
AW: Arbeiten mit TThreadList
Zitat:
Meinte natürlich dich :-D:-D Verd*mt, hab euch glatt verwechselt. Wie peinlich :lol::lol: Also, natürlich hast du es auf den Punkt gebracht. Großes Sorry |
AW: Arbeiten mit TThreadList
Hi, ich muß diese Thema noch mal aufwärmen, da ich da noch ein paar Probleme habe.
Also ich erzeuge mir eine TThreadList, die ich beim Beenden des MainThread entfernen möchte.
Delphi-Quellcode:
Sicherlich nicht korrekt, denn im FormDestroy kommt es beim RS232ThreadList.Free zu einer Exception, da die Thread noch nicht beendet sind.
procedure Tfrm_main.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var I: Integer; r: Cardinal; begin for I := RS232ThreadList.Count-1 downto 0 do begin TComThread(RS232ThreadList[i]).StopListen; TComThread(RS232ThreadList[i]).Terminate; r:=WaitForSingleObject(TComThread(RS232ThreadList[i]).Handle, 1000); //ShowMessage(IntToStr(r)); end; end; procedure Tfrm_main.FormCreate(Sender: TObject); begin RS232ThreadList:=TObjectList.Create; end; procedure Tfrm_main.FormDestroy(Sender: TObject); begin RS232ThreadList.Free; end; Bzw. genau genommen, lande ich in System.Classes im Destructor TThread.Destroy beim CloseHandle; Meine Annahme, die Threads in der ThreadList sind noch nicht beendet. Wie mache ich es richtig? Ich muß ja im OnCanClose auf das Beenden der Threads warten. |
AW: Arbeiten mit TThreadList
Zeig mal
a) wie du die Threads erzeugst (FreeOnTerminate?) b) wie du die Liste erzeugst (OnwsObjects?) |
AW: Arbeiten mit TThreadList
Wieso wartest Du nur maximal eine Sekunde auf das Handle? Warte doch lieber, bis das Handle die Fahne oben hat, auch wenn's dauert...
Und falls es sich dabei um Threads handelt, würde ich mit 'WaitFor' noch warten, bis das Teil auch wirklich beendet ist und es dann ggf. explizit per Free freigeben (außer, das macht die ThreadListe selbst) |
AW: Arbeiten mit TThreadList
Mit OwnObject:=False funktionierts. FreeOnTerminate ist True.
Jetzt werden die Objecte (Thread) also freigegen, wenn die Liste freigegeben werden. Aber eigentlich müßte es ja auch anders gehen. Ist denn das mit Waitforsingleobject so korrekt? Was ist eigentlich der Rückgabewert von Waitforsingleobject? In meinem Fall habe ich immer 0 zurück bekommen. Das mit 1000 Milisekunden ist erst mal zum Testen gewesen. Mit WaitFor on OnCanClose bekomme ich immer die EThread-Exception "Das Handle ist ungültig(6)". |
AW: Arbeiten mit TThreadList
Das ist die
Delphi-Quellcode:
aus
TThreadList
Delphi-Quellcode:
oder
System.Classes
Delphi-Quellcode:
, oder? Ich kann der nichts abgewinnen: Da fehlen elementarste Dinge wie ein
System.Generics.Collections
Delphi-Quellcode:
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?
GetEnumerator()
Ich nehme da einfach eine ganz "normale" Objektliste (
Delphi-Quellcode:
)- Soweit die
TObjectList
Delphi-Quellcode:
hat, ist die Freigabe der Liste mitsamt aller enthaltenen Threads so einfach wie ein
OwnsObjects = True
Delphi-Quellcode:
Bsp:
meineListe.Free();
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
Delphi-Quellcode:
einmal auskommentieren und dir den Unterschied anschauen :-)
{$DEFINE OWNSOBJECTS}
|
AW: Arbeiten mit TThreadList
Zitat:
Besser FreeOnTerminate auf false und dafür OwnsObjects auf true. Dann bleiben die Instanzen der Threads auch nach dem Beenden gültig und werden erst mit der Freigabe der Liste auch freigegeben. |
AW: Arbeiten mit TThreadList
Danke, FreeOnTerminate hab ich auf False gesetzt.
@Günther: Das werd ich mir auch noch mal genau anschauen. Aber das mit WaitForSingleObject hab ich noch nicht verstanden. Rückgabewert hab ich in OH gefunden. Aber mit dem Satz "The state of the specified object is signaled" ist mir noch nicht ganz klar. Heißt das jetzt, WaitForSingleObject wartet auf irgendeine Reaktion vom Object? |
AW: Arbeiten mit TThreadList
Zitat:
Danke für einen Hinweis, Christoph |
AW: Arbeiten mit TThreadList
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:04 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