Entwickler-Ecke

Internet / Netzwerk - urldownloadtofile sprengt systemspeicher


Delphi-Fan - So 04.11.07 14:43
Titel: urldownloadtofile sprengt systemspeicher
Hallo,
Ich habe ein Programm Geschrieben mit dem man Dateien von einer liste Nacheinander downloaden kann.

ich verwende urldownloadtofile.

zum testen habe ich eine sehr lange Dateiliste angegeben.

das Problem:

Irgendwann erscheint die Meldung:
"Systemressourcen verbraucht"

Bestätigte ich diese Meldung erscheinen in wilder Folge:
"Zugriff verweigert"
"Falscher Parameter"
und einige mehr.

Ich habe das Programm bei Laufendem Taskmanager noch mal die Liste abarbeiten lassen und beobachtet, das die Speicherauslastung durch mein Programm bei jeder Datei steigt.

Der Code enthällt nur eine for-schleife
und den urldownloadtofile-Befehl.

Wie kann ich verhindern, dass mein Programm immer mehr Speicher frisst?
Oder was ist der Grund für die steigende Speicherauslastung?

MfG
Delphi-Fan


Reinhard Kern - So 04.11.07 16:22
Titel: Re: urldownloadtofile sprengt systemspeicher
user profile iconDelphi-Fan hat folgendes geschrieben:

...
Wie kann ich verhindern, dass mein Programm immer mehr Speicher frisst?
Oder was ist der Grund für die steigende Speicherauslastung?

MfG
Delphi-Fan


Der Grund ist ein Programmfehler (what else) - einen solchen kann man aber nur finden, indem man das Programm liest und analysiert.

Gruss Reinhard


Delphi-Fan - So 04.11.07 20:57

Das da ein Fehler ist mir klar, deshalb frage ich.

Nur denke ich, das UrlDownloadtofile irgendwie Speicher verbraucht und erst wieder Freigibt wenn das Programm das UrlDownloadtofile aufgerufen hat beendet wird.

Das ist der Teil für den Download:


Delphi-Quelltext
1:
2:
3:
4:
for i:= 0 to Memo1.Lines.Count -1 do
begin
   UrlDownloadtofile(nil,Memo1.Lines[i],Edit1.Text+'\'+ExtractHttpFilename(Memo1.Lines[i]),0,nil);
end;


ExtractHttpFilename() macht das selbe wie ExtractFileName, nur für Internetpfade.
Und mehr Quellcode gibt es nicht.

Auf dem Form ist nur ein TEdit, ein TMomo und ein TButton;


JayEff - So 04.11.07 22:32

Hm. War es nicht so, dass der URL-Befehl einen Thread startet? Wieviele Dateien werden heruntergeladen? Es spalten sich die Geister, einer sagt, mehr als 16 Threads pro Programm sind ungesund, andere reden von 225...


Reinhard Kern - Mo 05.11.07 03:12

user profile iconJayEff hat folgendes geschrieben:
Hm. War es nicht so, dass der URL-Befehl einen Thread startet? Wieviele Dateien werden heruntergeladen? Es spalten sich die Geister, einer sagt, mehr als 16 Threads pro Programm sind ungesund, andere reden von 225...


Hallo,

dann würde ich es doch einfach mal mit dem Win32-Original von UrlDownloadToFile versuchen, das tut nichts dergleichen. Ausserdem liefert es ein Ergebnis des Downloads zurück (normalerweise S_OK), also wird tatsächlich eine Datei nach der anderen geladen. Wenns denn sein muss, kann man sich ja immer noch 3 oder 4 Threads einrichten - 200 Dateien parallel abzurufen macht dagegen eh keinen Sinn und die Sache nicht schneller.

Gruss Reinhard


Delphi-Fan - Do 08.11.07 19:00

Was meinst du mit "Win32-Original von UrlDownloadToFile"?


Mitmischer 1703 - Do 08.11.07 20:09

Ich würd sagen ProcessMessages/HandleMessages. Damit die anderen Programme nicht helfen, dein System zu "sprengen"! :lol:


Reinhard Kern - Fr 09.11.07 02:55

user profile iconDelphi-Fan hat folgendes geschrieben:
Was meinst du mit "Win32-Original von UrlDownloadToFile"?


Wenn dir das Win32-API nicht bekannt ist, vergiss den Vorschlag.

Gruss Reinhard


jaenicke - Fr 09.11.07 11:10

user profile iconDelphi-Fan hat folgendes geschrieben:
Was meinst du mit "Win32-Original von UrlDownloadToFile"?
Woher hast du denn die Funktion, die dir erlaubt Strings anzugeben? Wenn es ganz normal machst (also nur die Unit Urlmon einbindest), dann musst du da PChars angeben und keine Strings...

Die originale Funktionsdeklaration sieht so aus:
http://msdn2.microsoft.com/en-us/library/ms775123.aspx


Reinhard Kern - Fr 09.11.07 16:51

user profile iconjaenicke hat folgendes geschrieben:
user profile iconDelphi-Fan hat folgendes geschrieben:
Was meinst du mit "Win32-Original von UrlDownloadToFile"?
Woher hast du denn die Funktion, die dir erlaubt Strings anzugeben? Wenn es ganz normal machst (also nur die Unit Urlmon einbindest), dann musst du da PChars angeben und keine Strings...

Die originale Funktionsdeklaration sieht so aus:
http://msdn2.microsoft.com/en-us/library/ms775123.aspx


Hallo jaenicke,

war auch mein erster Gedanke, aber anscheinen gibt es auch noch ein UrlDownloadToFile aus einer Delphi-Unit, die den API-Aufruf kapselt (und u.a. keine Funktion ist und andere Parameter hat). Wenn darin, wie jemand vermutet hat, ein extra Thread gestartet wird, dann ist das Problem erklärlich, daher mein Vorschlag, der ja mit deinem übereinstimmt.

Der Fragesteller weiss aber offensichtlich nicht, dass hinter Delphi ein Win32-API steht.

Gruss Reinhard


Delphi-Fan - Fr 09.11.07 17:00

Dann verwende ich das Orginal...

Ich hab die funktion mit


Delphi-Quelltext
1:
2:
3:
4:
function UrlDownloadToFile(p1:IUnknown;source,target:String;p4:Cardinal;StatusCallBack:IBindStatusCallback):HRESULT; override;
begin
Result:=inherited URLDownloadToFIle(p1,PChar(source),PChar(target),p4,StatusCallBack);
end;


überschrieben, weil sie so leichter zu verwenden ist.

Edit:


Delphi-Quelltext
1:
2:
3:
4:
function UrlDownloadToFile(p1:IUnknown;source,target:String;p4:Cardinal;StatusCallBack:IBindStatusCallback):HRESULT;
begin
Result:=Urlmon.URLDownloadToFIle(p1,PChar(source),PChar(target),p4,StatusCallBack);
end;


So ist es überladen, das oben war aus dem Gedächtnis.
Hab ich mit einer anderen Überladung verwechselt. :lol:


jaenicke - Fr 09.11.07 19:16

Dann benutzt du ja die API-Funktion, das ist ja ok, auch wenn dein Code etwas seltsam aussieht...
Wie wäre es, wenn du die Funktion einfach anders nennst anstatt override und inherited zu benutzen? Denn das ist AFAIK eigentlich für Klassen vorgesehen, die von einer Oberklasse abgeleitet sind, nicht für einzelne Funktionen.

Ich werde mal die Funktion testen, und das Testprogramm auf Speicherlecks prüfen.