![]() |
Daten Kopieren mit Thread?
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:
Nun habe ich aber festgestellt, das wenn größere Datenmengen Transportiert, das er nicht weiterkomperliert bis die Datei oder Verzeichnis erfolgreich beendet wurde.
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; Meine Idee war die Funktion in einem Thread zu haun und dann nur die Parameter zu übergeben.
Delphi-Quellcode:
aber da ist wieder das Problem das er erst nach meiner For - Schleife mit den kopieren anfängt.
LThread := MyThread.Create(true);
LThread.GPfadFrom := LPfadFrom; LThread.GFadTo := LPfadTo; LThread.Suspended := False; //thread wird gestartet!! Application.ProcessMessages; 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:
...Die Dateien kopiert..
repeat
FileCountTo := TMyDaten.CountFiles(LPfadTo); //ermittelt OrdnerZahl Progressbar1.Position := FileCountTo; Application.ProcessMessages; until FileCountTo = FFileCountFrom; danke schonmal im Vorraus. |
AW: Daten Kopieren mit Thread?
Ü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.
|
AW: Daten Kopieren mit Thread?
Hallo erst mal :)
Kurz mal ein Hinweis zu
Delphi-Quellcode:
-- wenn du also Threads nutzen willst, unbedingt absolute Pfade verwenden:
ShFileOperation()
Zitat:
Zitat:
Delphi-Quellcode:
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
LThread := MyThread.Create(true);
LThread.GPfadFrom := LPfadFrom; LThread.GFadTo := LPfadTo; LThread.Suspended := False; //thread wird gestartet!! Application.ProcessMessages;
Delphi-Quellcode:
, d.h. du solltest es so machen:
Start()
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 |
AW: Daten Kopieren mit Thread?
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:
Ich will das das Programm die pfade aus der Datenbank liest und alle nach und Kopiert und den Fortschritt in eine Progressbar anzeigt.
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. |
AW: Daten Kopieren mit Thread?
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.
|
AW: Daten Kopieren mit Thread?
oder wie ziemlich weit oben schon erwähnt wurde das OnTerminate des Threads verwenden.
|
AW: Daten Kopieren mit Thread?
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. ![]() |
AW: Daten Kopieren mit Thread?
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? |
AW: Daten Kopieren mit Thread?
Zitat:
|
AW: Daten Kopieren mit Thread?
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 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