Entwickler-Ecke

Internet / Netzwerk - Programm friert bei verwendung von DownloadURL ein


the-chosen1 - Do 25.02.10 19:32
Titel: Programm friert bei verwendung von DownloadURL ein
Hey Leute ;)

Hab folgendes Problem... Ich will über DownloadURL (über TActionList) verschiedene Dateien rundter laden. Da diese Aber bis zu 5Mb groß sind, friert das Programm für eine beträchtliche Zeit ein :(
Wie kann ich denn das programm so schreiben, das Ich das programm weiter verwenden kann, während er im Hintergrund die Datei herunter läd?


PS: Ich bin mitlerweile wieder ziemlich aus der Übung hab seit über 2 Jahren nicht mehr mit Delphi gearbeitet :?


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Do 25.02.2010 um 21:19


Boldar - Do 25.02.10 19:34

Threads verwenden. Da solltest du hier im Forum einiges finden. Beim DelphiTreff gibt es glaube ich auch ein Tut, und hier vermutlich auch.


elundril - Do 25.02.10 19:35

Hallo und :welcome: im DF,

die Lösung die du suchst wäre ein Thread.

lg elundril

//edit: zu langsam :(


the-chosen1 - Do 25.02.10 21:21

mmhm werd ich machen

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Naja zu früh gefreut :(
Ich bekomm es zwar hin mehrere downloads gleichzeitig zu starten, das programm friert aber dennoch ein :(

Vieleicht hat jemand ein Tip für micht? Bzw. Einen Link, zu einem Forumsbeitrag, der mir weiter helfen könnte :)

Mein Problem jedenfall: Ein thread ist ja kein eigenständiges programm... Folglich ist der thread auch nicht in der Lage, die Datei herunter zu laden :(


Delete - Do 25.02.10 21:48

Ohne Code und ohne zu sehen, was du machst, wird man dir schlecht helfen können.


Xentar - Do 25.02.10 23:01

user profile iconthe-chosen1 hat folgendes geschrieben Zum zitierten Posting springen:
Mein Problem jedenfall: Ein thread ist ja kein eigenständiges programm... Folglich ist der thread auch nicht in der Lage, die Datei herunter zu laden :(

Ahja.. und der Firefox startet sich selbst mehrmals, wenn ich 3 Dateien gleichzeitig downloade? Na, auf die Erklärung bin ich gespannt..


Delete - Do 25.02.10 23:09

user profile iconthe-chosen1 hat folgendes geschrieben Zum zitierten Posting springen:
Mein Problem jedenfall: Ein thread ist ja kein eigenständiges programm... Folglich ist der thread auch nicht in der Lage, die Datei herunter zu laden :(

Hä? Was willst du uns damit sagen? Warum sollte ein Thread keinen Download durchführen können?


the-chosen1 - Do 25.02.10 23:10

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Ahja.. und der Firefox startet sich selbst mehrmals, wenn ich 3 Dateien gleichzeitig downloade? Na, auf die Erklärung bin ich gespannt..

Nee... Vieleicht bin ich einfach zu blöd... Jedenfalls hab ich nach einigen Tutorials versucht ein Thread zu erstellen -> Jedenfalls ist es mir nie gelungen "DownloadURL" zu verwenden...

Womöglich ist es auch unnötig... Falls jemand ein emöglichkeit hat -> Ich möchte im prinzim nur eine Datei im hintergrund runterladen, am besten noch mit fortschrittsanzeige... Jedenfalls dachte ich, das würde über DownloadURL funktionieren :D

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Hä? Was willst du uns damit sagen? Warum sollte ein Thread keinen Download durchführen können?

Sagen wir es anderst... Ich bekomm es ihrgendwie nicht hin :D


Boldar - Do 25.02.10 23:17

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Ohne Code und ohne zu sehen, was du machst, wird man dir schlecht helfen können.


Astat - Do 25.02.10 23:50

Hallo the-chosen1....


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
uses
  windows;

function URLDownloadToFile(Caller: IUnknown; URL: PChar; FileName: PChar;
  Reserved: DWORD; StatusCB: IUnknown): HResult; stdcall;
  external  'URLMON.DLL' name 'URLDownloadToFileA';

function lpThreadFunc(ptrData: Pointer): Integer;
begin
  result := URLDownloadToFIle(nil, PChar(ParamStr(1)),
    PChar(ParamStr(2)), 0nil);
end;

var
  dwThreadID: LongWord;
  hThread: LongWord;
begin
  hThread := BeginThread(nil0, lpThreadFunc, nil0 , dwThreadID);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
end.


lg. Astat


Xentar - Fr 26.02.10 00:03

Ist ja schön.. du startest nen Thread, nur um eine Zeile sptäer zu warten, bis er fertig ist.


Astat - Fr 26.02.10 00:14

Hallo Xentar, hast recht, mein Fehler, anbei der Rest.


Delphi-Quelltext
1:
2:
3:
program Project1;

{$APPTYPE CONSOLE}


lg. Astat


Xentar - Fr 26.02.10 00:27

Ändert nichts an der Tatsache, dass du wartest, bis der thread fertig ist.


Astat - Fr 26.02.10 00:52

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Ändert nichts an der Tatsache, dass du wartest, bis der thread fertig ist.


Jupp, richtig! aber! :mahn:

Ein Thread ist immer einem bestimmten Prozess zugeordnet und existiert nur innerhalb dieses Prozesses.
Prozess Weg = Thread weg = nix Downlod from URL!!

lg. Astat


elundril - Fr 26.02.10 00:56

aber hast du dann nicht das gleiche problem wie ohne thread? du startest deinen thread und sagst deinem hauptthread in dem auch die VCL ist das er auf den 2. Thread warten soll. Demnach ist der VCL-Thread wieder blockiert, was du ja eigentlich vermeiden wolltest weil du ja auf parallelität abzielst.

lg elundril


Xentar - Fr 26.02.10 01:05

user profile iconAstat hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Ändert nichts an der Tatsache, dass du wartest, bis der thread fertig ist.

Ein Thread ist immer einem bestimmten Prozess zugeordnet und existiert nur innerhalb dieses Prozesses.
Prozess Weg = Thread weg = nix Downlod from URL!!

Glaub, ich versteh dein Problem langsam, drück dich doch mal klarer aus ;)

Naja, was soll die Anwendung denn machen, während sie wartet? Irgendwas anderes anzeigen?
Oder nichts? Wenn ja, gib ihr halt trotzdem was zu tun.. warte nicht INFINITE, sondern mit ner While Schleife immer ein kleines bisschen, und gib der Anwendung so Zeit, auf Ereignisse zu reagieren (und somit nicht einfriert)


Astat - Fr 26.02.10 01:13

Hallo, es ging primär darum, wie man URLDownloadToFile in einem Thread aufrufen kann, bzw. wie man
einen Thread dafür verwendet.
Das Codeschnipsel sollte nur dies zeigen, und ist deshalb in einer Consolen Applikation implementiert.

Also, man nehme,


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
  CloseHandle(BeginThread(nil0, lpThreadFunc, nil0 , dwThreadID));
end;


und schon ist dieses eine Problem beseitigt.

lg. Astat


the-chosen1 - Fr 26.02.10 21:42

user profile iconAstat hat folgendes geschrieben Zum zitierten Posting springen:
Hallo the-chosen1....


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
uses
  windows;

function URLDownloadToFile(Caller: IUnknown; URL: PChar; FileName: PChar;
  Reserved: DWORD; StatusCB: IUnknown): HResult; stdcall;
  external  'URLMON.DLL' name 'URLDownloadToFileA';

function lpThreadFunc(ptrData: Pointer): Integer;
begin
  result := URLDownloadToFIle(nil, PChar(ParamStr(1)),
    PChar(ParamStr(2)), 0nil);
end;

var
  dwThreadID: LongWord;
  hThread: LongWord;
begin
  hThread := BeginThread(nil0, lpThreadFunc, nil0 , dwThreadID);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
end.


lg. Astat


Tut mir leid, euch so auf die Nerven zu gehen, aber ihrgendwie hab ich das noch nicht ganz verstanden, ich hab mich hier im Forum schon erkundigt und sehr lange gegoogelt, aber nichts wirkliches gefunden...

Also:
Wenn ich es richtig verstanden habe brauche ich zwei threads: Meinen Hauptthread, den ich brauch, damit mein Programm stabil bleibt, wenn ich eine Operation durchführe. Zudem brauche ich einen Zweiten, der während der Verwendung des Hauptthreads die Datei runterläd. (Hintergrund download)
Also muss ich einen Thread erstellen?
Über File -> New -> Other -> Thread object
(Sry hab nur die englische version)
In den Thread muss jetzt die Operation Reingeschrieben werden?
Allerdings komm ich hier nie Weiter... Ich hab schon versucht in dem Thread ein DownloadURL zu definierten - hab auch schon mit dem INDY HTML tool rumgespielt, komm aber leider nicht weiter :(

Um mit meinem Problem weiter zu gehen... Ich will eine Webseite herunterladen und sie nach bildern Durchsuchen (mit PosEx)... Allerdings ist diese Aktion recht Rechenaufwendig. Da der Download ja keine (kaum) rechenleistung benötigt, könnte ich jetzt doch einfach (theoretisch) einen weiteren Thread bauen, der während die Seite durchsucht wird, beginnt die nächste schon herunter zu laden

:)


Xentar - Fr 26.02.10 22:01

Und der Quellcode, mit dem du es probiert hast, lautet wie ... ?


Delete - Fr 26.02.10 22:55

Ich glaube, wir haben noch nicht genug gebettelt. :?


elundril - Fr 26.02.10 22:58

Can i haz Sourzecode plz?

user defined image


the-chosen1 - Sa 27.02.10 01:46

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Can i haz Sourzecode plz?

Sorry, nen source code hab ich nicht... Hab mehrere Stunden rumprobiert, hab deswegen alle paar minuten den Code verändert, und nichts mehr :(
Jedenfalls ist es schon relativ früh gescheitert, wie ich ja beschrieben hab :(

Moderiert von user profile iconNarses: Zitat repariert.


Delete - Sa 27.02.10 02:02

Und woher sollen wir dann wissen, was du falsch machst? Ohne Code werden wir dir nicht helfen können. Punkt.


the-chosen1 - Sa 27.02.10 13:14

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Und woher sollen wir dann wissen, was du falsch machst? Ohne Code werden wir dir nicht helfen können. Punkt.


Ja du hast recht, aber ich hab ja auch seite 1 mein vorgehen beschrieben... Würd mich interessieren, ob das soweit überhaupt richtig ist...