![]() |
ListView wird anscheinend vor Destroy-Aufruf zerstört
Hallo,
ich habe einen ListView-Komponente entwickelt die mit einem ThumbnailThread Thumbs aus Bildern generiert und anzeigt. In der ListView.Destroy Routine wird natürlich auch der Thread sauber beendet. Das hat beim Entwickeln der Komponente(dynamisch erzeugt) auch super geklappt. Jetzt soll die Komponente in einem größeren Projekt laufen und ich habe das Problem, dass wenn die Applikation während des Renderns beendet wird der Thread eine Zugriffsverletzung schmeißt, da er nicht mehr auf ListView.Items[x] zugreifen kann. Genau das ist ja eigentlich unmöglich, da der Thread in der Destroy-Routine heruntergefahren werden sollte. Bei der dynamischen Erzeugung habe ich zum Beispiel in MainForm.Destroy auch ListView.Destroy aufgerufen. Das müsste doch bei den Komponenten automatisch geschehen. Was läuft da falsch??? Viele Grüße Sebastian |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
ich denke mal ein wenig Sourcecode könnte hilfreich sein. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
Ich hoffe auf einen Referenzfall.. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
Zitat:
Hast Du eine Chance das ganze mal im Einzelschritt zu testen? BTW: Ich würde statt des Destroy eher Free oder FreeAndNil benutzen. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Erstmal vielen Dank für deinen Support trotz Code-Verweigerung.
Wie gesagt, liegt der Code nun als Komponente vor und ich rufe Destroy nicht selber auf, es handelt sich um den überschriebenen Destruktor:
Delphi-Quellcode:
Der Thread ist gerade dabei das hier auszuführen wenn der Fehler geworfen wird:
destructor TImgStdListView.Destroy;
begin if Assigned(FThumbnailThread) then begin SuspendThread; FThumbnailThread.Terminate; FThumbnailThread.Resume; WaitForSingleObject(FThumbnailThread.Handle, 3000); end; if Assigned(FDirWatcherThread) then begin FDirWatcherThread.Terminate; WaitForSingleObject(FDirWatcherThread.Handle, 3000); end; if Assigned(FCacheList) then begin ClearTransferList; FCacheList.Free; end; if Assigned(FObjectList) then FObjectList.Free; if Assigned(FMemoryInfo) then FMemoryInfo.Free; OleUnInitialize; inherited; end;
Delphi-Quellcode:
Nur sollte Items noch vorhanden sein, solange Destroy nicht durchlaufen wurde.
if FListView.Items[I].ImageIndex = 0 then
Hat beim Entwickeln auch IMMER funktioniert. auch ohne Synchronize. Grüße Sebastian [EDIT:] Durchsteppen ist schwierig, da ich auf Anhieb nicht erkenne wann der ListView zerstört wird. Wo geschieht das durch eine Parent-Komponente genau? |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
also ohne Synchronize auf eine VCL-Kompo zuzugreifen ist, genaugenommen, sträflicher Leichtsinn ;-) Zitat:
Der Parent ist nur für die Position zuständig. An welcher Stelle sollte denn der Listview zerstört werden? Zitat:
Zitat:
Zitat:
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
Zitat:
Zitat:
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Wenn der Zugriff auf Items[I].ImageIndex vom Thread aus synchronized gemacht wird, gibt es dieselbe Zugriffsverletzung. Habe ich mir schon gedacht. (Der Aufruf Items[I].Index befindet sich nun in einer protected-Methode des ListViews.) Nur wenn ich hier vorher
Delphi-Quellcode:
aufrufe vermeide ich die Zugeiffsverletzung. Das ist nicht optimal und ich verstehe immer noch nicht warum die Items vor dem ListView.Destroy zerstört werden. Kann mir das mal jemand erklären?
if (csDestroying in ComponentState) then
Exit; Wie gesagt während der Entwicklung der Komponente (dynamische Erzeugung) gab es das Problem einfach nicht. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
inzwischen sind mir noch ein paar Dinge aufgefallen: Was macht SuspendThread? Wozu noch Resume nach Terminate? Warum verlässt Du Dich, ohne weitere Prüfung, darauf, dass WaitForSingleObject zurückkehrt weil der Thread beendet wurde? Vielleicht ist der Return Code ja WAIT_TIMEOUT, weil der Thread noch läuft. Wo wird der ListView erzeugt? In Deine Kompo? In diesem Falle könntest Du als Owner ja nil angeben, und den ListView gezielt nach dem Thread zerstören. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
Zitat:
Wenn Du selber die Steuerung übernimmst, wann der ListView zerstört wird, kann er Dir auch nicht vor dem Zerstören des Thread "unter den Füssen weggezogen" werden |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
waurm werden denn die Items vor dem Destroy-Aufruf auf nil gesetzt? |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
Zitat:
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Der ListView wird als Komponente auf das Formular gezogen. Es liegt also nicht direkt in meiner Hand. Ich denke der Owner ist das Panel in dem er drinliegt.
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
das hatte ich befürchtet (und erwartet ;-)) Dann sehe ich (nur) folgende Möglichkeiten:
Punkt 2 dürfte wohl mit Abstand am einfachsten umzusetzen sein. |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
|
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Moin Sebastian,
Zitat:
Also ich hatte es so verstanden, dass der ListView von Dir auf das Formular gezogen wird, und Deine eigene Kompo, die den Thread erzeugt auch. Der ListView wird der anderen Kompo dann übergeben. Oder nicht, oder doch, oder wie... :gruebel: |
Re: ListView wird anscheinend vor Destroy-Aufruf zerstört
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 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