Entwickler-Ecke

Internet / Netzwerk - IdHTTP Downloadzeit berechnen?


jackie05 - Do 22.10.09 19:46
Titel: IdHTTP Downloadzeit berechnen?
Hallo,
ich versuche die verbleibende Zeit von Downloads zu berechnen, leider erhalte ich immer fogende fehlermeldung:

Delphi-Quelltext
1:
2:
Project Project1.exe raised exception class EInvalidOp with message 'Invalid floating point operation'.
Process stopped. Use Step or Run to continue.


und hier mal das OnWorkBegin und OnWork ereignis:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
procedure TDownloadThread.HTTPWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
var
  TotalTime: TDateTime;
  H, M, Sec, MS: Word;
  DLTime: Double;
  AverageSpeed, temp: Extended;
  Zeit : string;
begin
  MinKB := AWorkCount;
  Form1.liste.Items[ItemNR].SubItems[2] := IntToStr(MaxKB div 1024)+' KB';

  TotalTime :=  Now - STime;
  DecodeTime(TotalTime, H, M, Sec, MS);
  Sec := Sec + M * 60 + H * 3600;
  DLTime := Sec + MS / 1000;                         //Ausrechnung des downloadspeeds
  if DLTime > 0 then
    AverageSpeed := (AWorkCount / 1024) / DLTime;
  Speed := FormatFloat('0 KB/s', AverageSpeed);

  if not(AverageSpeed=0then temp:=((MaxKB - MinKB) / 1024) / AverageSpeed else temp:=0;
  if temp>0 then
  begin
    if temp>=60 then
    begin
      if temp>=3600 then
      begin
        Zeit:=FloatToStr(temp/60);
        Zeit:=Copy(zeit, 03) + 'h';                          //zeit verbleibend
      end;
      Zeit:=FloatToStr(temp/60);
      Zeit:=Copy(zeit, 03) + 'm';
    end
    else
      Zeit:=FloatToStr(temp) + 's';
  end
  else
    Zeit:='0s';

  Form1.liste.Items[ItemNR].SubItems[4] := Zeit+' '+Speed;

  Application.ProcessMessages;
end;

procedure TDownloadThread.HTTPWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
begin
  STime:=Now;
  MaxKB := AWorkCountMax;
  Form1.liste.Items[ItemNR].SubItems[2] := IntToStr(MaxKB div 1024)+' KB';
  Application.ProcessMessages;
end;


Der Fehler liegt in Zeile 21-38.
Wie kann ich das Problem beheben?
Oder gibt es noch andere wege die Verbleibende Zeit zu berechnen?

Ich bedanke mich schonmal im Voraus.

MfG


jaenicke - Do 22.10.09 19:59

Du prüfst AverageSpeed auf exakt 0, aber es kann auch 0,00000000000000000001 oder sowas sein. Das fängst du aber nicht ab, so dass dann ein Fehler auftreten kann.

Du müsstest also eine eigene Toleranz einführen oder direkt Math.IsZero nutzen.


jackie05 - Do 22.10.09 20:47

Vielen Dank.
Ich hab das mal so versucht:

Delphi-Quelltext
1:
2:
FloatToStr(AverageSpeed);
  if not(round(AverageSpeed)=0then temp:=round(((MaxKB - MinKB) / 1024) / round(AverageSpeed)) else temp:=0;


habe mein Quelltext nur um diese Zeile ergänzt:

Delphi-Quelltext
1:
FloatToStr(AverageSpeed);                    


und komischerweise funktioniert jetzt alles.

MfG


Delete - Fr 23.10.09 00:36

Du hast da einen Thread für den Download. Aber warum benutzt du Application.ProcessMessages? Desweiteren ist es keine gute Idee unsynchronisiert auf Elemente des Formulares zuzugreifen, da die VCL nicht threadsicher ist.


jaenicke - Fr 23.10.09 05:52

:oops: Das ist natürlich richtig. Dass das ein Thread ist, ist mir gar nicht aufgefallen, die Klassenbezeichnung habe ich nicht weiter beachtet.


jackie05 - Sa 24.10.09 17:18

Danke euch.
Ich hatte Application.ProcessMessage da stehen, da ich es erst ohne Threads gemacht habe und es dann mit Threads umgeschrieben hab.

Noch eine Frage habe ich.
Wie kann ich vor dem Downloaden der Datei, die Größe auslesen?

Danke schonmal.

MfG


jaenicke - Sa 24.10.09 17:32

user profile iconjackie05 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich vor dem Downloaden der Datei, die Größe auslesen?
Das sollte im Header stehen, wenn du diesen abrufst. Genauer gesagt in Content-Length.


jackie05 - Sa 24.10.09 17:40

Ich habe das so versucht:

Delphi-Quelltext
1:
2:
HTTP.Get(DownloadURL);
DownloadSize := HTTP.Request.ContentLength;


das funktioniert aber nicht so.
Ich möchte die Größe auslesen lassen, bevor die Datei erstellt bzw. heruntergeladen wird, weil ich erst auf ein Button klicken muss, um dann den Download zu starten.

Wie mache ich das jetzt?

MfG


jaenicke - So 25.10.09 19:28

Ich sagte ja auch nur etwas davon den Header abzurufen, nicht die ganze Datei mit Get...
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdCustomHTTP_Head@string.html