![]() |
TThread in Liste sauber aufräumen
Hallo,
ich möchte ein Programm schreiben, in dem Dateien per Thread überwacht werden. (Dazu gibt es ja schon etliche Theme ebenso wie zur Verwaltung von Thread. Aber daraus bin ich nicht wirklich schlau geworden.) Momentan wird nur hochgezählt. Den Dateinamen schreibe ich in eine Liste. Es ist FreeOnTerminate:=True gesetzt, so dass ich mich um das aufräumen nicht mehr kümmern muss. Am Ende von Excute rufe ich dann (Synchronized) eine Procedure auf, in der noch der Listeneintrag gelöscht wird. Läuft der Thread komplett durch, ist alles OK. Ich habe aber ein Problem, wenn ich das Programm vorher beende. In OnCloseQuery gehe ich die Liste durch und rufe die Procedure Terminate auf und Lösche den Listeneintrag. Jetzt habe ich ein Speicherleck (gemäß Meldung von FastMM4.94). Wenn ich zusätzlich noch .Free aufrufe, dann bekomme ich eine Exception:
Delphi-Quellcode:
Wo liegt hier mein Fehler?
Type
TOpenThread = Class(TThread) Public FileName : String; Protected TFCount : Int64; Procedure Progress; Procedure Execute; Override; Procedure CleanUp; End; TForm1 = Class(TForm) ThreadList : TListBox; BtnStart : TButton; ODiag : TOpenDialog; Procedure BtnStartClick(Sender: TObject); Procedure FormCloseQuery(Sender: TObject; Var CanClose: Boolean); End; ... Procedure TOpenThread.Progress; Var I : Integer; Begin I:=Form1.ThreadList.Items.IndexOfObject(self); Form1.ThreadList.Items.Strings[I]:=FileName + ' ' +FormatFloat('0,', TFCount); End; Procedure TOpenThread.Execute; Var I : Integer; Begin I:=0; While (Not Terminated) And (I < 150000) Do Begin Inc(I); TFCount:=I; Synchronize(Progress); End; Synchronize(CleanUp); End; Procedure TOpenThread.CleanUp; Var I : Integer; Begin I:=Form1.ThreadList.Items.IndexOfObject(self); Form1.ThreadList.Items.Delete(I); End; Procedure TForm1.BtnStartClick(Sender: TObject); Var OThread : TOpenThread; Begin If ODiag.Execute Then Begin OThread:=TOpenThread.Create(True); OThread.FreeOnTerminate:=True; OThread.FileName:=ODiag.FileName; OThread.Priority:=tpIdle; ThreadList.AddItem(ODiag.FileName, OThread); OThread.Resume; End; End; Procedure TForm1.FormCloseQuery(Sender: TObject; Var CanClose: Boolean); Begin If ThreadList.Count = 0 Then CanClose:=True Else If MessageBox(0, 'Sollen noch laufende Threads beendet werden?', 'Sicherheitsabfrage', mb_YESNO Or mb_IconQuestion) = idYES Then Begin While ThreadList.Count > 0 Do Begin TOpenThread(ThreadList.Items.Objects[0]).Terminate; // TOpenThread(ThreadList.Items.Objects[0]).WaitFor; // TOpenThread(ThreadList.Items.Objects[0]).Free; ThreadList.Items.Delete(0); End; CanClose:=True; End Else CanClose:=False; End; End. Gruß, Alex |
Re: TThread in Liste sauber aufräumen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
also ich habe jetzt dieses ![]() Soll das nur daran liegen, dass es keine TObjectList ist? Ich habe aber gerade eine TListBox gewählt, weil ich während des Programmierens "zum Debuggen" eine Ausgabe sehen will ... Der Code ist jetzt zum Testen anbei. Ich begreife es einfach nicht! Gruß, Alex |
Re: TThread in Liste sauber aufräumen
1. Du musst den Destructor schon überschreiben.
2. Warum benutzt du eine ThreadList, wenn du a) diese nur im MainThread verwendest und b) du sowieso nicht die eigentliche Funktionalität der ThreadList (Methode: LockList) verwendest? Edit: 2A ist im angehängten Projekt entfallen, da du ja jetzt nicht mehr synchronize verwendest, und damit die ThreadList von beiden Threads benutzt wird --> LockList verwenden. Edit2: Und außerdem löschst du die Listenelemente gleich zweimal in CleanUp und in FormDestroy. |
Re: TThread in Liste sauber aufräumen
Hallo Sirius,
Zitat:
Zitat:
Mein Fernziel ist es später, das jeder Thread seine eigene Datei überwacht. Es sind Textdateien. In der Textverarbeitung ist Autosave und sonstwas an und wir haben ein sehr langsames VPN. Der Thread soll die Datei nach TEMP kopieren, mit dem verknüpften Programm dort starten und nach dem Ende wieder an den Ursprungsort zurück verfrachten. -> Ich dachte dafür wäre ein Thread wie geschaffen. Hier teste ich doch nur! Zitat:
Zitat:
Mein Problem ist auch nicht, dass es nicht klappt, sondern die "komische" Fehlermeldung: Thread-Fehler: Das Handle ist ungültig (6) Und dass obwohl ich den Code aus meiner Fundstelle bis auf den Thread 1:1 abgeschrieben habe. [edit]Mit 1:1 abgeschriebenem Code kommt schon beim Anlegen des Thread diese Fehlermeldung: Exception der Klasse EAbstractError mit der Meldung 'Abstrakter Fehler'.[/edit] Bitte nicht hauen: Es gibt bei TObjectList die Eigenschaft OwnsObjects. Wenn ich die auf True setze, dann müssten doch die Threads beim Beenden mit platt gemacht werden, oder? Gruß und Danke, Alex |
Re: TThread in Liste sauber aufräumen
Zitat:
Zitat:
Zitat:
Zitat:
Wird nur Free aufgerufen, aber nicht beendet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:20 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