Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TShellTreeView Speicherlecks (https://www.delphipraxis.net/140168-tshelltreeview-speicherlecks.html)

RaSoWa1 12. Sep 2009 08:30


TShellTreeView Speicherlecks
 
Hallo,

Bei der Suche nach Speicherlecks in einem gößeren Programm, habe ich festgestellt, das diese z.T. von der TShellTreeView-Komponente stammten.

Ich habe in der ShellCtrls.pas folgende Änderungen vorgenommen:
1. eine Destroy-Methode in TCustomShellTreeView eingefügt und FRootFolder und FNotifier freigegeben.
Delphi-Quellcode:
destructor TCustomShellTreeView.Destroy;
begin
  if Assigned(FRootFolder)
  then FRootFolder.Free;
  If Assigned(FNotifier)
  then FNotifier.Free;
  inherited Destroy;
end;
2. Der nachfolgende Thread fragt Terminated nicht ab, weil er in WaitForMultipleObjects auf irgendwas ewig wartet. Deshalb habe ich statt INFINITE eine Zeit festgelegt.
Delphi-Quellcode:
procedure TShellChangeThread.Execute;
var
  Obj: DWORD;
  Handles: array[0..1] of DWORD;
begin
  EnterCriticalSection(CS);
  FWaitHandle := FindFirstChangeNotification(PChar(FDirectory),
     LongBool(FWatchSubTree), FNotifyOptionFlags);
  LeaveCriticalSection(CS);
  if FWaitHandle = ERROR_INVALID_HANDLE then Exit;
  while not Terminated do
  begin
    Handles[0] := FWaitHandle;
    Handles[1] := FMutex;
//    Obj := WaitForMultipleObjects(2, @Handles, False, INFINITE);
    Obj := WaitForMultipleObjects(2, @Handles, False, 500);   // neue Zeile von RaSoWa
    case Obj of
      WAIT_OBJECT_0:
        begin
          Synchronize(FChangeEvent);
          FindNextChangeNotification(FWaitHandle);
        end;
      WAIT_OBJECT_0 + 1:
        ReleaseMutex(FMutex);
      WAIT_FAILED:
        Exit;
    end;
    EnterCriticalSection(CS);
    if FWaitChanged then
    begin
      FWaitHandle := FindFirstChangeNotification(PChar(FDirectory),
         LongBool(FWatchSubTree), FNotifyOptionFlags);
      FWaitChanged := false;
    end;
    LeaveCriticalSection(CS);
  end;
end;
FastMM4 findet nach diesen Änderungen keine diesbezüglichen Speicherlecks mehr. Das Programm läuft jetzt auch ohne Fehlermeldungen.
Da diese API-Programmierung nicht gerade meine Stärte ist, habe ich folgende Fragen:
Worauf wartet der Thread in WaitForMultipleObjects?
Welche Nebenwirkungen können auftreten, wenn ich, wie oben angegeben, die Wartezeit begrenze?

Vielleicht kann jemand meine Fragen beantworten.
Vielen Dank im Vorraus.

Klaus

Phoenix 12. Sep 2009 08:46

Re: TShellTreeView Speicherlecks
 
Die ShellTreeView komponenten sind nicht nur mit Speicherlecks durchzogen sondern auch noch so richtig Buggy. Ab und an kann es passieren, dass eine Anwendung bei der Verwendung dieser Komponenten ins Nirvana wegploppt (ganz seltsamer Fehler, den wir von Delphi-Anwendungen eigentlich nur seltenst kennen. *Plopp*, Fenster & Prozess weg. Ohne Fehlermeldung oder sonstiges).

Es sind halt nur Demos und keine 'richtigen' Komponenten. Leider merkt man das sehr stark, wenn man sich auf die Dinger verlässt.

Schau Dir mal die ShellTools von http://www.mustangpeak.net/ an. Die sind soweit ich das mitbekommen habe um längen tauglicher.

DeddyH 12. Sep 2009 08:54

Re: TShellTreeView Speicherlecks
 
Noch eine kleine Bemerkung:
Zitat:

Delphi-Quellcode:
if Assigned(FRootFolder)
then FRootFolder.Free;

Free prüft intern bereits auf Assigned, so dass die vorherige Abfrage entfallen kann.

RaSoWa1 12. Sep 2009 09:18

Re: TShellTreeView Speicherlecks
 
@DeddyH:
Zitat:

Free prüft intern bereits auf Assigned, so dass die vorherige Abfrage entfallen kann.
Danke. Du hast Recht. Ich habe meinen Code bereis geändert.

@Phoenix:
Zitat:

Schau Dir mal die ShellTools von http://www.mustangpeak.net/ an. Die sind soweit ich das mitbekommen habe um längen tauglicher.
Danke für den Tip. Ich schau sie mir mal.
Mit der TShellTreeView-Komponente hatte ich bisher noch keine direkten Probleme. Allerdings kann sie durch die jetzt bemerkten Speicherlecks Ursache für andere eigenartige Probleme gewesen sein.

GPRSNerd 12. Sep 2009 22:26

Re: TShellTreeView Speicherlecks
 
Hi, die Destroy-Methode gab es bei mir schon und wenigstens FRootFolder wurde schon freigegeben:

Delphi-Quellcode:
destructor TCustomShellTreeView.Destroy;
begin
  ClearItems;
  FRootFolder.Free;
  inherited;
end;
Der Code ist Delphi 2009 Update 3.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz