Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dynamisches Array "weg" nach Thread beendigung (https://www.delphipraxis.net/68882-dynamisches-array-weg-nach-thread-beendigung.html)

C.Schoch 7. Mai 2006 14:18


Dynamisches Array "weg" nach Thread beendigung
 
Hi,
Ich habe einen dynamischen Array Typ welcher im Thread code deklariert ist.
Delphi-Quellcode:
TArrayofStringList = packed array of TStringList; // Typ im Thread
Im Haupt Formular erstelle ich dann eine Variable dieses Typs welche an den Thread übergeben wird.
Delphi-Quellcode:
SourceFileList : tSearchFiles.TArrayofStringList; //  Deklaration im Hauptcode
DestThread.FileList := DestFileList; // Übergabe an den Thread
Diese Variable wird im Thread an eine Procedure übergeben in der ich "setlegth" aufrufe um das array nach meinen wünschen zu vergrößern.
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?

mkinzler 7. Mai 2006 14:38

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.

C.Schoch 7. Mai 2006 14:43

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?

mkinzler 7. Mai 2006 14:47

Re: Dynamisches Array "weg" nach Thread beendigung
 
Zitat:

Ich habe einen dynamischen Array Typ welcher im Thread code deklariert ist.
Lies diese Aussage nicht erahnen.
Zeig mal ein bischen mehr Code.

C.Schoch 7. Mai 2006 15:07

Re: Dynamisches Array "weg" nach Thread beendigung
 
Aufruf:
Delphi-Quellcode:
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;
Thread:
Delphi-Quellcode:
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.
ich denke das sollte reichen
aber nicht gleich wegen irgendwelche bezeichnernamen verhauen.
der Typ ist eigendlich nur wegen der Procedure, da ich sonst nichts übergeben kann.

SirThornberry 7. Mai 2006 15:26

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.

C.Schoch 7. Mai 2006 15:50

Re: Dynamisches Array "weg" nach Thread beendigung
 
köntest du mal ein beispiel machen wo ich den Pointer benutzen soll und wie?

SirThornberry 7. Mai 2006 15:59

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;
[...]

C.Schoch 7. Mai 2006 18:38

Re: Dynamisches Array "weg" nach Thread beendigung
 
So übergeben:
Delphi-Quellcode:
 SourceThread.FileList := @SourceFileList;
und so aufrufen:
Delphi-Quellcode:
  GetFiles(sDir, FileList^, '*.*', true);
oder muss ich auch im Threadcode dann mit dem Pointer weiterarbeiten?
ich liebe pointer. :twisted:

SirThornberry 7. Mai 2006 18:40

Re: Dynamisches Array "weg" nach Thread beendigung
 
genau so sollte es eigentlich funktionieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:57 Uhr.
Seite 1 von 2  1 2      

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