![]() |
Dynamisches Array "weg" nach Thread beendigung
Hi,
Ich habe einen dynamischen Array Typ welcher im Thread code deklariert ist.
Delphi-Quellcode:
Im Haupt Formular erstelle ich dann eine Variable dieses Typs welche an den Thread übergeben wird.
TArrayofStringList = packed array of TStringList; // Typ im Thread
Delphi-Quellcode:
Diese Variable wird im Thread an eine Procedure übergeben in der ich "setlegth" aufrufe um das array nach meinen wünschen zu vergrößern.
SourceFileList : tSearchFiles.TArrayofStringList; // Deklaration im Hauptcode
DestThread.FileList := DestFileList; // Übergabe an den Thread das geht soweit alles gut bis der Thread beendet wird, dann kann ich nicht mehr auf das Array zugreifen obwohl es noch Arbeitspeicher verbraucht. der Thread wird mehrmals aufgerufen. Kann es sein dass der speicher dem Array nach der beendigung des Threads nicht zugeordnet bleibt? Wenn ja warum? |
Re: Dynamisches Array "weg" nach Thread beendigung
Die (Poiter-)Variable existiert nur so lang wie der Thread. Der Inhalt des Arrays belibt aber bestehen. Beim nächsten Durchlauf wird neuer Speicher auf dem Heap angefordert. Du mußt diese varibale außerhalb des Threads deklarieren, dann wird bei jedem Thread-Durchlauf der gleiche Speicher verwendet.
|
Re: Dynamisches Array "weg" nach Thread beendigung
Ich hab die Variable ja außerhalb des Threads im Haupt Formular deklariert. oder muss auch der Typ außerhalb deklareirt werden?
|
Re: Dynamisches Array "weg" nach Thread beendigung
Zitat:
Zeig mal ein bischen mehr Code. |
Re: Dynamisches Array "weg" nach Thread beendigung
Aufruf:
Delphi-Quellcode:
Thread:
procedure TMainForm.btBackupClick(Sender: TObject);
var i, j, k, l : integer; WaitResult : DWORD; begin btBackup.Enabled := false; btCancel.Enabled := true; bCanceled := false; for i := 0 to lvSourceDestination.Items.Count - 1 do begin if bCanceled then begin break; end; DestThread := TtSearchFiles.create(true); SourceThread := TtSearchFiles.create(true); SortThread := TtSortFiles.Create(true); DestThread.sDir := lvSourceDestination.Items[i].SubItems[1]; SourceThread.sDir := lvSourceDestination.Items[i].SubItems[0]; DestThread.FileList := DestFileList; SourceThread.FileList := SourceFileList; SortThread.sDestDir := lvSourceDestination.Items[i].SubItems[1]; SortThread.sSourceDir := lvSourceDestination.Items[i].SubItems[0]; DestThread.Resume; SourceThread.Resume; SortThread.Resume; ThreadArray[0] := DestThread.Handle; ThreadArray[1] := SourceThread.Handle; ThreadArray[2] := SortThread.Handle; repeat WaitResult := msgWaitforMultipleObjects(length(ThreadArray) - 2, ThreadArray, true, 1000{INFINITE}, QS_ALLINPUT); if WaitResult <> WAIT_OBJECT_0 then begin Application.ProcessMessages; end; end; end;
Delphi-Quellcode:
ich denke das sollte reichen
unit tSearchFiles;
interface uses Classes, Windows, dialogs; type TArrayofStringList = packed array of TStringList; TtSearchFiles = class(TThread) private iDirCount : Integer; protected procedure Execute; override; procedure GetFiles(const Directory : string; var Files : TArrayofStringList; (*type TArrayofStringList = packed array of TStringList;*) const FileMask : string = '*.*'; const SubFolders : Boolean = True); public sDir : String; // wird übergeben vom Haupt code FileList : TArrayofStringList; // wird übergeben vom Haupt code end; implementation uses Sysutils, MainFrame; { TSearchFiles } ///////////////////////////GetFiles///////////////////////////////////////////// // Autor: Daniel B // Editor: C.Schoch //////////////////////////////////////////////////////////////////////////////// procedure tTSearchFiles.GetFiles(const Directory : string; var Files : TArrayofStringList; const FileMask : string = '*.*'; const SubFolders : Boolean = True); function SlashSep(const Path, S : string): string; // Backslash zum Pfadende hinzufügen wenn keiner vorhanden begin if AnsiLastChar(Path)^ <> '\' then Result := Path + '\' + S else Result := Path + S; end; var SearchRec : TSearchRec; begin // Verzeichniss nach Dateien durchsuchen SetLength(Files,iDirCount+1); // hier set length Files[iDirCount] := TStringList.Create; if FindFirst(SlashSep(Directory, FileMask), faAnyFile - faDirectory - faVolumeID, SearchRec) = 0 then begin if not Terminated then begin try repeat Files[iDirCount].Add(SlashSep(Directory, SearchRec.Name)); until (FindNext(SearchRec) <> 0) or Terminated; finally SysUtils.FindClose(SearchRec); end; end; end; if SubFolders and not Terminated then begin // Unterordner suchen inc(iDirCount); if FindFirst(SlashSep(Directory,'*.*'), faAnyFile, SearchRec) = 0 then begin try repeat if (SearchRec.Attr and faDirectory) <> 0 then begin if ((SearchRec.Name <> '.') and (SearchRec.Name <> '..')) then begin GetFiles(SlashSep(Directory, SearchRec.Name),Files,FileMask, SubFolders); end; end; until FindNext(SearchRec) <> 0; finally SysUtils.FindClose(SearchRec); end; end; end; end; //////////////////////////////////////////////////////////////////////////////// procedure TtSearchFiles.Execute; begin iDirCount := 0; MainForm.test1 := true; GetFiles(sDir, FileList, '*.*', true); MainForm.test1:= false; end; end. aber nicht gleich wegen irgendwelche bezeichnernamen verhauen. der Typ ist eigendlich nur wegen der Procedure, da ich sonst nichts übergeben kann. |
Re: Dynamisches Array "weg" nach Thread beendigung
ich würde behaupten das auf diese Art und weise der Inhalt des Arrays kopiert wird. Denn dadurch das du im Thread das Array normal definierst ist dort auch ein richtiges Array vorhanden (und nicht nur ein Pointer). Du solltest also im Thread einen Pointer auf das Array verwenden.
|
Re: Dynamisches Array "weg" nach Thread beendigung
köntest du mal ein beispiel machen wo ich den Pointer benutzen soll und wie?
|
Re: Dynamisches Array "weg" nach Thread beendigung
so:
Delphi-Quellcode:
[...]
type TArrayofStringList = packed array of TStringList; PArrayOfStringList = ^TArrayOfStringList; // <= hier wurde hinzugefügt TtSearchFiles = class(TThread) private iDirCount : Integer; protected procedure Execute; override; procedure GetFiles(const Directory : string; var Files : TArrayofStringList; (*type TArrayofStringList = packed array of TStringList;*) const FileMask : string = '*.*'; const SubFolders : Boolean = True); public sDir : String; // wird übergeben vom Haupt code FileList : PArrayofStringList; // <= hier wurde geändert end; [...] |
Re: Dynamisches Array "weg" nach Thread beendigung
So übergeben:
Delphi-Quellcode:
und so aufrufen:
SourceThread.FileList := @SourceFileList;
Delphi-Quellcode:
oder muss ich auch im Threadcode dann mit dem Pointer weiterarbeiten?
GetFiles(sDir, FileList^, '*.*', true);
ich liebe pointer. :twisted: |
Re: Dynamisches Array "weg" nach Thread beendigung
genau so sollte es eigentlich funktionieren.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 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