AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Daten Kopieren mit Thread?

Ein Thema von WizoHulk · begonnen am 27. Nov 2010 · letzter Beitrag vom 4. Dez 2010
Antwort Antwort
WizoHulk

Registriert seit: 25. Jun 2010
198 Beiträge
 
Delphi 5 Enterprise
 
#1

Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 07:25
Hallo DP's

ich hab ein kleines Problem, und zwar möchte ich Dateien kopieren. was soweit auch ganz gut mit den Source klappt.
Delphi-Quellcode:
class function TMyDaten.CopyDirectory(AFromFolder, AToFolder: string): boolean;
var
  fos: TSHFileOpStruct;
begin
  ZeroMemory(@fos, SizeOf(fos));
  fos.wFunc := FO_COPY;
  fos.fFlags := FOF_SIMPLEPROGRESS OR FOF_NOCONFIRMATION;
  fos.pFrom := PChar(AFromFolder + #0);
  fos.pTo := PChar(AToFolder);
  Result := (0 = ShFileOperation(fos));
end;
Nun habe ich aber festgestellt, das wenn größere Datenmengen Transportiert, das er nicht weiterkomperliert bis die Datei oder Verzeichnis erfolgreich beendet wurde.
Meine Idee war die Funktion in einem Thread zu haun und dann nur die Parameter zu übergeben.
Delphi-Quellcode:
LThread := MyThread.Create(true);
      LThread.GPfadFrom := LPfadFrom;
      LThread.GFadTo := LPfadTo;
      LThread.Suspended := False; //thread wird gestartet!!
      Application.ProcessMessages;
aber da ist wieder das Problem das er erst nach meiner For - Schleife mit den kopieren anfängt.

hat jemand eine Idee wie man das am einfachsten lösen kann?
Mein ziel ist, das er währen meiner Fußgesteuerten schleife...
Delphi-Quellcode:
repeat
        FileCountTo := TMyDaten.CountFiles(LPfadTo); //ermittelt OrdnerZahl
        Progressbar1.Position := FileCountTo;
        Application.ProcessMessages;
      until FileCountTo = FFileCountFrom;
...Die Dateien kopiert..

danke schonmal im Vorraus.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 08:55
Übergib dem Thread doch einen Zeiger auf eine Array mit allen zu kopierenden Ordnern (vorher sammeln) und lass Dich im OnTerminate informieren wenn er fertig ist.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#3

AW: Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 10:01
Hallo erst mal

Kurz mal ein Hinweis zu ShFileOperation() -- wenn du also Threads nutzen willst, unbedingt absolute Pfade verwenden:
Zitat von http://msdn.microsoft.com/en-us/library/bb762164%28VS.85%29.aspx:
You should use fully-qualified path names with this function. Using it with relative path names is not thread safe.
Nun habe ich aber festgestellt, das wenn größere Datenmengen Transportiert, das er nicht weiterkomperliert bis die Datei oder Verzeichnis erfolgreich beendet wurde.
Ich glaube, du verwechselst hier was oder solltest dir darüber klar werden, was unter compilieren zu verstehen ist. Du meinst wohl, dass das Programm nicht mehr reagiert, wenn du große Dateien kopierst?!

Delphi-Quellcode:
LThread := MyThread.Create(true);
      LThread.GPfadFrom := LPfadFrom;
      LThread.GFadTo := LPfadTo;
      LThread.Suspended := False; //thread wird gestartet!!
      Application.ProcessMessages;
Irgendwie seltsamer Code Das mit den Properties kannst du so handhaben, das geht schon in Ordnung. Für das Starten des Threads gibt es doch die Methode Start() , d.h. du solltest es so machen:

Delphi-Quellcode:
LThread := MyThread.Create(true);
LThread.GPfadFrom := LPfadFrom;
LThread.GFadTo := LPfadTo;
LThread.Start(); // ab hier läuft dann der Kopierthread los
// Application.ProcessMessages; <<< das hier braucht es nicht
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
WizoHulk

Registriert seit: 25. Jun 2010
198 Beiträge
 
Delphi 5 Enterprise
 
#4

AW: Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 16:51
das mit dem Thread haut hin.
jetzt will ich aber prüfen ob er denn Fertig ist mit der übertragung, damit er mit der neuen Operation anfangen kann daten zu kopieren.
hatte das mit einer schleife gemacht. das klappt aber auch net so ganz.

am besten ich zeug ma den ganzen source um überhaupt da mal durchzublicken...

Delphi-Quellcode:
unit Unit1;

procedure TForm1.ConnectToDB;
var
  LDBPfad: String ;
begin
  LDBPfad := TMyDaten.GetMyPath;
    FDBPfad := LDBPfad + 'MyDatenbank.accdb'; // D:\FastBackup\MyDatenbank.accdb
    try
  // adoConBackupper.Connected := true;
      adoConBackupper.ConnectionString := TMyaccessDB.ConnectionToACCDB(FDBPfad);
     //adoConBackupper.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + FDBPfad +';Persist Security Info=False';
      lProcessStatus.Caption := 'Verbindung zur Datenbank wird aufgebaut...';
    except
      lProcessStatus.Caption := 'Fehler beim Verbinden...';
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

    GlassFrame.Enabled:= true;
    Height := 0;
    left := Screen.Width - Width;
    top := Screen.Height;
    Timer2.enabled := true;
end;

procedure TForm1.StartingProcess;
var
    LThread: MyThread;
    lFileCountFrom, LRecordCount: Integer;
    LSql,LDateNow,LBackupString: String;
    LStatus, LPfadFrom, LPfadTo : String;
    LAddDate, LReplaceDate,LReplaceFolder,LDateiCode, LAddBackupString: Boolean;
    LReccord: Integer;
    I,x: Integer;
begin
  ConnectToDB;

  QuerryBackupper.Close;
  QuerryBackupper.SQL.Text := 'SELECT COUNT (*) FROM MyBackup WHERE deltag = ''t'' and Status = ''aktiv''';
  QuerryBackupper.open;
  LRecordCount := QuerryBackupper.Fields[0].asInteger;
  QuerryBackupper.Close;


  TMyaccessDB.SelectQuerry(QuerryBackupper,
                            'id, backupname,Pfad, Pfad_export,add_date,replace_folder,datei_code,add_backup_string',
                            'MyBackup','deltag = ''t'' and Status = ''aktiv''');



  while not QuerryBackupper.Eof do
  begin

    LReccord := QuerryBackupper.FieldByName('id').AsInteger;

    LStatus := QuerryBackupper.FieldByName('backupname').AsString;//LStatus
    LPfadFrom:= QuerryBackupper.FieldByName('pfad').AsString;
    LPfadTo:= QuerryBackupper.FieldByName('Pfad_export').AsString;
    LAddDate := QuerryBackupper.FieldByName('add_date').AsBoolean;
    LReplaceFolder := QuerryBackupper.FieldByName('replace_folder').AsBoolean;
    LAddBackupString := QuerryBackupper.FieldByName('add_backup_string').AsBoolean;
    Application.ProcessMessages;

    lProcessStatus.Caption := 'Starte mit der Archivierung...';
    //Strings in Arrays
    Setlength(FaStatus,length(FaStatus)+1);
    FaStatus[Length(FaStatus)-1] := Lstatus;//Backupname
    Setlength(FaPfad,length(FaPfad)+1);
    FaPfad[Length(FaPfad)-1] := LPfadFrom;//Pfad
    Setlength(Fapfadto,length(Fapfadto)+1);
    Fapfadto[Length(Fapfadto)-1] := LPfadTo;//Pfad Export
    //Boolean als Arrays
    Setlength(FaAddDate,length(FaAddDate)+1);
    FaAddDate[Length(FaAddDate)-1] := LAddDate;//add_date
    Setlength(FaReplaceFolder,length(FaReplaceFolder)+1);
    FaReplaceFolder[Length(FaReplaceFolder)-1] := LReplaceFolder;//replace Folder
    Setlength(FAddBackupString,length(FAddBackupString)+1);
    FAddBackupString[Length(FAddBackupString)-1] := LAddBackupString;//Pfad Export

    QuerryBackupper.Next;
  end;

  adoConBackupper.Connected := false;

  for i := 0 to LRecordCount -1 do
    begin
      Lstatus := FaStatus[i];
      LPfadFrom := FaPfad[i];
      LPfadTo := Fapfadto[i];

      LAddDate := FaAddDate[i];
      LReplaceFolder := FaReplaceFolder[i];
      LAddBackupString := FAddBackupString[i];

      FFileCountFrom := TMyDaten.CountFiles(LPfadFrom);
      //ist Einstellung AddDate true dann Datum erstellen
      if LAddDate = true then
       LDateNow := DateToStr(now);

      // is Einstellung auf true, dann wird in exportpfad'backup hinzugefügt'
      if LAddBackupString = true then
        LBackupString := '- Backup';

      //LPfadTo :=LPfadTo + LBackupString + '-' + LStatus + LDateNow;
      LPfadTo :=LPfadTo + '\' + LStatus + LBackupString + LDateNow;//pfad zu lang


      LThread := MyThread.Create(true);
      LThread.GPfadFrom := LPfadFrom;
      LThread.GFadTo := LPfadTo;
      LThread.Start;

     repeat
       FileCountTo := TMyDaten.CountFiles(LPfadTo); //ermittelt OrdnerZahl
        Progressbar1.Position := FileCountTo;
        Application.ProcessMessages;
      until FileCountTo = FFileCountFrom;
     ProgressBar1.Position:= 0;
      Application.ProcessMessages;
    end;//for i
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if Height > 150 then
  begin
    Timer2.Enabled := false;
    StartingProcess;
  //
  end
   else
    begin
      LockWindowUpdate(Handle);
      try
        Height := Height + 5;
        top := Screen.WorkAreaHeight - Height;
        //top := Screen.Height - Height;
      finally
        Lockwindowupdate(0);
      Application.BringToFront;
      end;
    end;
end;

end.
Ich will das das Programm die pfade aus der Datenbank liest und alle nach und Kopiert und den Fortschritt in eine Progressbar anzeigt.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 17:06
Eine Möglichkeit wäre, dass du dir vom Thread am Ende eine Nachricht schicken lässt. Oder du nutzt die Methode WaitFor aus der Thread Klasse.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Daten Kopieren mit Thread?

  Alt 27. Nov 2010, 19:14
oder wie ziemlich weit oben schon erwähnt wurde das OnTerminate des Threads verwenden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Daten Kopieren mit Thread?

  Alt 28. Nov 2010, 00:37
Oder man gibt dem Thread eine Queue. In die platziert man die Arbeitsaufträge.

Der Thread arbeitet diese nun einfach ab, bis die Warteschlange leer ist und legt sich dann schlafen (Suspended).
Wird ein neuer Auftrag in die Queue geschoben, weckt dieses Ereignis den Thread wieder auf.
Nach jedem Arbeitsauftrag kann der Thread noch einen Event abschicken, das der Auftrag xy abgearbeitet ist.

Deine Umsetzung mit dem Thread ist irgendwie so eine halbtags Sache zwischen Thread und doch nicht Thread. Der Thread kopiert die Daten und die Form kontrolliert wieviele Daten kopiert wurden.
Das ist nicht nur vom Ablauf suboptimal, sondern extrem ungeschickt.

Der Thread kann die Form auch informieren, ob er fertig ist, und zwischendurch den aktuellen Status (wieviele Dateien müssen noch, wieviele sind schon, wie heißt die aktuelle Datei die kopiert wird).
In der Form brauche ich keine Schleife, keinen Timer, sondern reagiere nur auf Events.

Hier wird quasi genau sowas gerade auch besprochen
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
WizoHulk

Registriert seit: 25. Jun 2010
198 Beiträge
 
Delphi 5 Enterprise
 
#8

AW: Daten Kopieren mit Thread?

  Alt 4. Dez 2010, 02:28
Hallo Leute,

ich habe jetzt ein Thread das mir Ordner von a nach b kopiert.
wenn es nur ein Satz mit Herkunftpfad und Zielpfad ist, klappt das ja super, bloß ic hhabe einen Array von Strings die nach und nach in dem Thread abgearbeitet werden sollen.
Habe es mit einer Schleife versucht, aber das haut nicht hin, er startet immer erst den Thread wenn die Procedure beendet ist.
Hat jemand eine Idee wie man das beheben kann?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

AW: Daten Kopieren mit Thread?

  Alt 4. Dez 2010, 03:24
Hat jemand eine Idee wie man das beheben kann?
Ohne Code kann man da schwer was zu sagen. ber ich würde das Array als Property an das Threadobjekt übergeben.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Daten Kopieren mit Thread?

  Alt 4. Dez 2010, 09:52
Obwohl ich ja dafür immer eine WorkQueue verwenden würde.

Dann ist es völlig egal, zu welchem Zeitpunkt die Anwendung eine Aktion anfordert.
Ob in einer Schleife aus einem Array oder durch einen Tastendruck vom User.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:32 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