![]() |
idHTTP.get Threads ( Multi Download )
hallo,
ich habe mir ein Programm geschrieben, welches mehrere Dateien gleichzeitig Downloaden soll. Hierzu habe ich Threads erstellt, in denen jeweils ein idHTTP läuft und die get methode ausgeführt wird. Die Threads laufen auch gleichzeitig, doch nun habe ich mir eine Fortschrittsanzeige eingebaut, welche die geladenen Bytes anzeigt und habe gesehen, dass jeweils nur ein Thread Fortschritt macht und die anderen stehen bleiben/warten. Um die Form am Leben zu halten benutze ich AntiFreeze. Weiß wer, wie ich es hinbekommen kann, dass alle Threads gleichzeitig laden? [Delphi7,indy10] |
Re: idHTTP.get Threads ( Multi Download )
Hi,
hast Du denn auch für jeden Download/Thread eine Progressbar gemacht ? Wie kommst Du darauf das die anderen Threads anhalten ? Weil Deine Fortschrittsanzeige stehen bleibt ? Ein bisschen mehr Infos und eventuell etwas Code, wie Du die Progressbar aus den Threads aktualisierst wäre hilfreich ;-) Greetz Data |
Re: idHTTP.get Threads ( Multi Download )
Irgendwas passt das nicht zusammen. Wenn du mit Threads arbeitest brauchst du kein Antifreece. Antifreece arbeitet mit Application.ProcessMessages welches nur auf den Hauptthread Anwendung findet.
|
Re: idHTTP.get Threads ( Multi Download )
Delphi-Quellcode:
Das soll meine Thread Klasse sein
type
TDownload = class(TThread) private URL:String; TITLE:String; HTTP:TidHTTP; protected procedure Execute; override; public procedure Set_Data(pURL,TITLE:String); end;
Delphi-Quellcode:
so schaut die execute procedure aus...
procedure TDownload.Execute;
var FS:TFileStream; slTime,elTime:TDateTime; fail:Boolean; Leechedsize,Filesize:int64; begin http := TidHTTP.Create; dir := appdir + 'data/download/'; FOrm1.p_download.Caption := 'Action: Trying ' + rls; Form1.lv_download.Items.Add.Caption := TITLE; gitem := Form1.lv_download.Items.Count-1; if DirectoryExists(dir) then begin Form1.lv_download.Items[gitem].SubItems.Add('Already Exists'); end else begin Form1.p_download.Caption := 'Action: Start Downloading ' + rls; Form1.lv_download.Items[gitem].SubItems.Add('Downloading'); slTime := now; FS:=Tfilestream.Create(dir + '/' + TITLE,fmCreate); fail := False; leechedsize := 0; http.Head(URL); filesize := http.Response.ContentLength; Form1.lv_download.Items[gitem].SubItems[0] := 'Downloading ('+GetSizeName(leechedsize)+'/'+GetSizeName(filesize)+')'; repeat if (filesize-leechedsize) > cFileSplitSize then Http.Request.Range := Format('%d-%d', [leechedsize, (leechedsize+cFileSplitSize-1)]) else Http.Request.Range := Format('%d-', [leechedsize]); try HTTP.Get(URL,FS); except fail := True; end; Form1.lv_download.Items[gitem].SubItems[0] := 'Downloading ('+GetSizeName(leechedsize)+'/'+GetSizeName(filesize)+')'; leechedsize := leechedsize+cFileSplitSize; until (leechedsize >= filesize); elTime := now - slTime; if fail then Form1.lv_download.Items[gitem].SubItems[0] := 'Download Failed' else Form1.lv_download.Items[gitem].SubItems[0] := 'Finished ('+FormatDateTime('hh:mm:ss',elTime)+')'; Form1.p_download.Caption := 'Action: Finished ' + rls; end; http.free; Inc(Form1.CurThreads,-1); end; und ich komme darauf, weil wenn ich nun einen Thread aufrufe, startet dieser und zeigt mir immer etwas Fortschritt an, aber sobald ich den zweiten Thread starte, kommt doch nichts mehr sondern nur noch beim zweiten... aufrufen tue ich den Thread über einen Timer: (DownQueue ist eine TList)
Delphi-Quellcode:
if CurThreads < MaxThreads then
begin if not DownQueue.isEmpty then begin Inc(CurThreads,1); DownQueue.toFirst; load := TDownload.Create(true); with (LeechQueue.getItem AS TLeechSettings) do load.Set_Data(Get_url,Get_title); DownQueue.remove; load.Execute; end; end; Zitat:
Habe ich vielleicht etwas beim Thread selber bzw. beim Aufbau falch gemacht oder vergessen ? |
Re: idHTTP.get Threads ( Multi Download )
surprise, surprise...
so ich habe mal etwas in der Aufruf-procedur geändert:
Delphi-Quellcode:
also FreeOnTerminate hinzugefügt und Resume statt Execute.. und nun gehts parallel.. Kann mir mal wer knapp den unterschied Erklären, wegen dem verständnis :) ?
if CurThreads < MaxThreads then
begin if not DownloadQueue.isEmpty then begin Inc(CurThreads,1); DownloadQueue.toFirst; load:= TLeech.Create(true); with (DownloadQueue.getItem AS TLeechSettings) do load.Set_Data(Get_url,Get_title); load.FreeOnTerminate := True; DownloadQueue.remove; load.Resume; end; end; |
Re: idHTTP.get Threads ( Multi Download )
Zitat:
|
Re: idHTTP.get Threads ( Multi Download )
^^ Genau Gausi hat recht, jeder GUI Zugriff aus einem Thread muss syncronisiert werden.
Das es jetzt läuft ist reine Glückssache ... Außerdem das Load.Execute direkt aufzurufen war/ist vollkommen sinnfrei, dann hättest Du auch gleich eine normale Procedure ohne Thread verwenden können. Load.Resume startet denn Thread und dieser ruft dann intern Execute auf. Hoffe das bringt das das Problem noch etwas näher. Greetz Data |
Re: idHTTP.get Threads ( Multi Download )
Also habe ich das so richtig verstanden, dass ich bei jedem zugriff auf das GUI bzw. eine locale Variable "Synchronize" verwenden sollte ?
also dann so:
Delphi-Quellcode:
procedure TDownload.Execute;
var FS:TFileStream; slTime,elTime:TDateTime; fail:Boolean; Leechedsize,Filesize:int64; begin http := TidHTTP.Create; dir := appdir + 'data/download/'; Synchronize(FOrm1.p_download.Caption := 'Action: Trying ' + rls); Synchronize(Form1.lv_download.Items.Add.Caption := TITLE); gitem := Synchronize(Form1.lv_download.Items.Count-1); if DirectoryExists(dir) then begin Synchronize(Form1.lv_download.Items[gitem].SubItems.Add('Already Exists')); end else begin Synchronize(Form1.p_download.Caption := 'Action: Start Downloading ' + rls); Synchronize(Form1.lv_download.Items[gitem].SubItems.Add('Downloading')); slTime := now; FS:=Tfilestream.Create(dir + '/' + TITLE,fmCreate); fail := False; leechedsize := 0; http.Head(URL); filesize := http.Response.ContentLength; {...} http.free; Synchronize(Inc(Form1.CurThreads,-1)); end; |
Re: idHTTP.get Threads ( Multi Download )
Hast du das mal getestet? Oder dich über TThread.Synchronize() erkundigt?
|
Re: idHTTP.get Threads ( Multi Download )
ehm ja gerade.. ^^
habe es getestet ging nicht.. Aber habe gefunden, dass der Zugriff in eine Procedur ausgelagert werden muss, dies habe ich jetzt getan und es geht. Kann es sein, dass man bei der Procedure keine Parameter übergeben darf, weil dann bekomme ich immer einen Error, allerdings ist dies denke ich egal, da man dies über die Private Variablen regeln kann. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:54 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