Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi idHTTP.get Threads ( Multi Download ) (https://www.delphipraxis.net/150171-idhttp-get-threads-multi-download.html)

LiB 9. Apr 2010 01:47


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]

DataCool 9. Apr 2010 07:49

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

SirThornberry 9. Apr 2010 08:29

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.

LiB 9. Apr 2010 11:48

Re: idHTTP.get Threads ( Multi Download )
 
Delphi-Quellcode:
type
  TDownload = class(TThread)
  private
    URL:String;
    TITLE:String;
    HTTP:TidHTTP;
  protected
    procedure Execute; override;
  public
    procedure Set_Data(pURL,TITLE:String);
  end;
Das soll meine Thread Klasse sein

Delphi-Quellcode:
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;
so schaut die execute procedure aus...
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:

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.
Hat mich auch stark gewundert.. aber trotz Thread hat Die Form sonst gehakt..
Habe ich vielleicht etwas beim Thread selber bzw. beim Aufbau falch gemacht oder vergessen ?

LiB 9. Apr 2010 12:22

Re: idHTTP.get Threads ( Multi Download )
 
surprise, surprise...

so ich habe mal etwas in der Aufruf-procedur geändert:

Delphi-Quellcode:
 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;
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 :) ?

Gausi 9. Apr 2010 12:29

Re: idHTTP.get Threads ( Multi Download )
 
Zitat:

Zitat von LiB
Habe ich vielleicht etwas beim Thread selber bzw. beim Aufbau falch gemacht oder vergessen ?

Ja. Von einem zweiten Thread aus darf man niemals direkt auf die Form zugreifen. Wenn auf der Form was geändert werden soll, kann man das z.B. per Synchronize machen. Dass das bei dir mit einem Thread so funktioniert hat, und mit deinen Änderungen jetzt wieder, ist reiner Zufall.

DataCool 9. Apr 2010 13:19

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

LiB 10. Apr 2010 00:41

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;

wicht 10. Apr 2010 00:48

Re: idHTTP.get Threads ( Multi Download )
 
Hast du das mal getestet? Oder dich über TThread.Synchronize() erkundigt?

LiB 10. Apr 2010 00:56

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.
Seite 1 von 2  1 2      

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