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 Verzeichnisse mit unsynchronisiertem Thread kopieren (https://www.delphipraxis.net/102106-verzeichnisse-mit-unsynchronisiertem-thread-kopieren.html)

MichaelN2703 23. Okt 2007 15:35


Verzeichnisse mit unsynchronisiertem Thread kopieren
 
Hallo,

ich möchte aus einer Anwendung heraus nach Auswahl des Nutzers zeitgleich mehrere Kopierprozesse zeitgleich starten.

Folgende Schritte werden beim kopieren ausgeführt:

1. Alle ausgewählten Programme werden als lokale Kopie im eingestellten Temp-Verzeichnis zwischengespeichert
2. Sollten im (bereits vorhandenen) Zielverzeichnis standortspezifische Dateien vorhanden sein, werden diese ebenfalls in diesem Tempverzeichnis zwischengespeichert
3. Zielverzeichnis wird gelöscht
4. Programm wird kopiert
5. Standortspezifische Dateien werden zurückgeschrieben
6. Tempverzeichnis wird gelöscht.

Ich hatte zuerst einen Thread erzeugt, in einer Schleife diesen wieder angestoßen, als globale Variable jeweils das Start- und das Zielverzeichnis übergeben. Das Problem war dann, das einige Verzeichnisse nicht kopiert wurden, also hatte ich mehrere Threads verwendet, jetzt klappte das kopieren.

Delphi-Quellcode:
case XX of
  1 : begin
        Zieldatei_1_Thread := Zieldatei;
        Quelldatei_1_Thread := Quelldatei;
        Zieldatei_2_1_Thread := Zieldatei_2;
        Quelle1 := FileListComplete[1].Location;
        Ziel1 := FileListComplete[UpdateIndex].Location;
        Programm1 := FileListComplete[1].FileParam[k_1].Name;
        MyThread_1 := TMyThread_1.create;
        MyThread_1.Resume;
        setlength(ThreadHandleListe,length(ThreadHandleListe)+1);
        ThreadHandleListe[length(ThreadHandleListe)-1] := MyThread_1.Handle;
      end;

  2 : begin
        Zieldatei_2_Thread := Zieldatei;
        Quelldatei_2_Thread := Quelldatei;
        Zieldatei_2_2_Thread := Zieldatei_2;
        Quelle2 := FileListComplete[1].Location;
        Ziel2 := FileListComplete[UpdateIndex].Location;
        Programm2:= FileListComplete[1].FileParam[k_1].Name;
        MyThread_2 := TMyThread_2.create;
        MyThread_2.Resume;
        setlength(ThreadHandleListe,length(ThreadHandleListe)+1);
        ThreadHandleListe[length(ThreadHandleListe)-1] := MyThread_2.Handle;
      end;
end;
Um die zwischengespeicherten Dateien zurückzuschreiben und das Tempverzeichnis wieder zu löschen warte ich am Ende der Schleife im Hauptprogramm auf das Ende der Threads:

Delphi-Quellcode:
WaitErgebnis:= WaitForMultipleObjects( length(ThreadHandleListe),@ThreadHandleListe[0],true,INFINITE);
Währen des Kopierprozesses soll als Caption eines Labels angezeigt werden, was gerade passiert, ich habe die Threads erweitert:

Delphi-Quellcode:
 
type
  TMyThread_2 = class(TThread)
  private

    { Private-Deklarationen }
  protected
    procedure Execute; override;

  public
    constructor create; virtual;
  end;


 
procedure TMyThread_2.Execute;
  var
  SHFileOp : TSHFileOpStruct;
  szFrom : array[0..128] of Char;
  szTo  : array[0..128] of Char;

  // Strings für Caption des Labels im Hauptformular
  Kopierhinweis_2: String;
  Kopierhinweis_3 : String;
  Quelle : String;
  Ziel : String;
  Programm : String;

  // Pfade
  Zieldatei_thread, Quelldatei_thread, Zieldatei_2 : String;


begin
  Quelle := Quelle2;     //globle Variable
  Ziel := Ziel2;          //globle Variable
  Programm := Programm2;  //globle Variable

  Kopierhinweis_3 := Kopierhinweis; //globle Variable
  Kopierhinweis_2 := '';
  Kopierhinweis_2 := Text_142 +  Programm + Text_143  + Quelle + Text_144 + Ziel;

  freeonterminate := False;
  Zieldatei_thread := Zieldatei_2_Thread;
  Quelldatei_thread := Quelldatei_2_Thread;
  Zieldatei_2 := Zieldatei_2_2_Thread;

  if DirectoryExists(ExcludeTrailingPathDelimiter(Zieldatei_2)) = False then
    CreateDir(ExcludeTrailingPathDelimiter(Zieldatei_2));

  // Puffervariablen initialisieren
  FillChar(SHFileOp, Sizeof(SHFileOp), #0);
  FillChar(szFrom, Sizeof(szFrom), #0);
  FillChar(szTo, Sizeof(szTo), #0);
  StrPCopy(szFrom, Quelldatei_thread);
  StrPCopy(szTo, Zieldatei_thread );
  try
  with SHFileOp do
  begin
    Wnd := application.Handle;
    wFunc := FO_COPY;
    pFrom := @szFrom;
    pTo :=@szTo;
    fFlags := FOF_NOCONFIRMATION or FOF_NOERRORUI or FOF_NOCONFIRMMKDIR;
  end;

  finally

  end;
  Kopierhinweis := Kopierhinweis_3 +#10#13 + Kopierhinweis_2 +  Text_146;
  freeonterminate := True;
  Exit;
end;


//-------- create (public) ---------------------------------------------
constructor TMyThread_2.create;
begin
  inherited create(true);
  Priority := tpIdle;
end;


Ich habe jetzt folgende Probleme:

Obwohl der Kopierprozess noch läuft (Fenster mit Progressbar der API) werden gelegentlich schon die nachfolgenden Schritte ausgeführt, da aber noch Daten kopiert werden wird u.a. das Tempverzeichnis nicht gelöscht.

Die Anwendung bremst das System stark aus, obwohl im Taskmanager weder CPU noch Speicher ausgelastet werden.

Der Inhalt der Kopierfenster wird kaum aktualisiert, auch in das Hauptfenster der Anwendung kommt man kaum zurück, die Anzeige des Labels ist somit kaum möglich.

Die Anwendung wird ausschließlich auf Netzlaufwerken ausgeführt, die Verbindung ist teilweise sehr langsam.

Die Anzahl der maximal möglichen Kopierprozesse habe ich auf 64 beschränkt (hatte ich als obere Grenze für WaitForMultipleObjects gefunden).

Kann mir jemand bei der Lösung meiner Probleme helfen?

DP-Maintenance 23. Okt 2007 15:48

DP-Maintenance
 
Dieses Thema wurde von "SirThornberry" von "Neuen Beitrag zur Code-Library hinzufügen" nach "VCL / WinForms / Controls" verschoben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:20 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