| Autor |
Beitrag |
Delphi-Fan
Hält's aus hier
Beiträge: 4
Win XP
Delphi 5
|
Verfasst: So 04.11.07 14:43
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
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: So 04.11.07 16:22
Delphi-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 
Hält's aus hier
Beiträge: 4
Win XP
Delphi 5
|
Verfasst: 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
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: 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
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Mo 05.11.07 03:12
JayEff 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 
Hält's aus hier
Beiträge: 4
Win XP
Delphi 5
|
Verfasst: Do 08.11.07 19:00
Was meinst du mit "Win32-Original von UrlDownloadToFile"?
|
|
Mitmischer 1703
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: Do 08.11.07 20:09
Ich würd sagen ProcessMessages/HandleMessages. Damit die anderen Programme nicht helfen, dein System zu "sprengen"! 
_________________ Die Lösung ist nicht siebzehn.
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Fr 09.11.07 02:55
Delphi-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
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 09.11.07 11:10
Delphi-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:
msdn2.microsoft.com/...ibrary/ms775123.aspx
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Fr 09.11.07 16:51
jaenicke hat folgendes geschrieben: | Delphi-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:
msdn2.microsoft.com/...ibrary/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 
Hält's aus hier
Beiträge: 4
Win XP
Delphi 5
|
Verfasst: 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. 
Zuletzt bearbeitet von Delphi-Fan am Fr 09.11.07 22:48, insgesamt 1-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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.
|
|