Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Laden von HTML-Seiten mit Multithread (https://www.delphipraxis.net/85416-laden-von-html-seiten-mit-multithread.html)

Gravitar 4. Feb 2007 12:59

Re: Laden von HTML-Seiten mit Multithread
 
Hi Pfoto,

dein Tipp

Delphi-Quellcode:
TMyThread = class(TThread)
private
  fIdHTTP: IdHTTP; <-- So! 
public
  procedure execute; override;
end;
funktioniert nicht. Müsste es nach OOP nicht fIdHTTP : TIdHTTP heissen? :wink:

Egal, funktioniert auch nicht, da nach Aufruf in der execute eine Acess-violation in Modul irgendwas auftaucht.

Gruß, Andreas

Antigo 4. Feb 2007 14:12

Re: Laden von HTML-Seiten mit Multithread
 
Acces Violation.. hört sich so an als hättest du das idHTTP Objekt nicht instanziert.

Gravitar 4. Feb 2007 15:24

Re: Laden von HTML-Seiten mit Multithread
 
Hi Antigo,

so, jetzt habe ich auch noch das IdHTTP-Objekt instanziiert.

Der Source sieht jetzt so aus:

Delphi-Quellcode:
TMyThread = class(TThread)
private
  fIdHTTP: TIdHTTP;
public
  procedure execute; override;
end;

...

procedure TMyThread.Execute;
var web : string;
    myidhttp : TIdHTTP;
begin
  myidhttp := tIdHTTP.Create();
  web := UTF8ToWideString(MyIdHTTP.get(form1.ListView1.Items[x].SubItems.Strings[4]));
  form1.ListView1.Items[x].SubItems.Strings[4] := web;
  myidhttp.Free;
end;
Ich gebe ja zu, dass ich mit dieser oop-Materie bisher wenig zu tun hatte, aber wozu habe ich jetzt eigentlich fIdHTTP deklariert?

Das Instanziieren habe ich über TIdHTTP vorgenommen (fidHTTP habe ich auch mal versucht, führt aber sofort zu einem Crash).

Mittlerweile gelingt es mir bis zur 5 Threads zu starten. Komischerweise bekomme ich aber nur 1 Ergebnis zurück (in Zeile 6!

Wenn ich 10 Threads starte, gibts wieder eine Access-Violation! :wall:

Das ganze kann doch so schwer nicht sein oder muss man dafür tatsächlich komplett OOP lernen?

Gruß, Andreas

Gravitar 6. Feb 2007 07:19

Re: Laden von HTML-Seiten mit Multithread
 
Hi,

mittlerweile klappt das Multithreading mit 6 parallelen Threads ganz gut.

Die Definition von fIdHTTP habe ich einfach weggelassen.

Das ich nur 1 Ergebnis zurückbekam lag offenbar an der globalen Variablen X, die nach Abschluß von idHTTP.get bereits auf 6 hochgezählt war und dann nur dorthin zurücklieferte.

Also habe ich einfach die globale Variable in eine lokale kopiert (schöner wäre es natürlich mit einer Variablenübergabe in Execute, aber ich habe keine Ahnung, wie das geht).

So, nun stellen sich "nur" noch die Frage:

Wieso gibt es eine Access-Violation, wenn mehr als 6 Threads gestartet werden? Windows verkraftet doch eine ganze Menge (>450 Threads bei ruhendem System).

Gruß, Andreas

Klaus01 6. Feb 2007 08:48

Re: Laden von HTML-Seiten mit Multithread
 
Vielleicht solltest Du den Zugriff auf VCL Elemente, wie die ListView, synchronisieren.
Ein Beispiel wie das geht findest Du hier -> http://greatis.com/delphicb/tips/lib...nchthread.html

Grüße
Klaus

Gravitar 8. Feb 2007 17:28

Re: Laden von HTML-Seiten mit Multithread
 
Hi,

Danke für die Tipps. Inzwischen habe ich nahezu alle umgesetzt. Der Source sieht jetzt so aus:

Delphi-Quellcode:
TMyThread = class(TThread)
private
  fIdHTTP: TIdHTTP;
  i : integer;
  web : string;
protected
  procedure GetResult;
  procedure execute; override;
public
end;

...

procedure tmythread.GetResult;
begin
  web := UTF8ToWideString(web);
  form1.ListView1.Items[i].SubItems.strings[4] := web;
end;

procedure TMyThread.Execute;
begin
  i := x;
  fIdHTTP := TIdHTTP.Create(nil);
  web := fIdHTTP.get(form1.ListView1.Items[i].SubItems.Strings[4]);
  Synchronize(GetResult);
end;
X und Web sind global definiert und dienen zur Übergabe.

Bei mehr als 10 Threads parallel kommt jetzt die Fehlermeldung "Socket Error #10060 Connection timed out".

Das hört sich jetzt nicht mehr nach einer Access-Violation an.

Weiss jemand Rat?

Gruß, Andreas

Pfoto 8. Feb 2007 17:39

Re: Laden von HTML-Seiten mit Multithread
 
Hi!

vielleicht ist die Wartezeit eines Threads beim
Zugreifen auf eine Seite nun einfach überschritten,
weil er aufgrund der hohen Auslastung nicht
zum Zuge kommt.


Gruß
Pfoto

Gravitar 8. Feb 2007 22:19

Re: Laden von HTML-Seiten mit Multithread
 
Hi,

so, dass Problem ist gelöst! Über 60 parallele HTTP.Get's werden ohne Fehler ausgeführt.

Erstaunlicherweise funktioniert der schon gezeigte Source ohne jede Änderung, wenn man nur in der Aufrufschleife ein "Application.Processmessages" einfügt! (habe ich eigentlich nur gemacht, um die Aktualisierung des ListView hinzubekommen.

Hier nun die komplette Lösung (für diejenigen, die ähnliche Probleme lösen müssen):


Delphi-Quellcode:
{Definition}
TMyThread = class(TThread)
private
  fIdHTTP: TIdHTTP;
  i : integer;
  web : string;
protected
  procedure GetResult;
  procedure execute; override;
public
end;

{Ergebniss des Threads auswerten}
procedure tmythread.GetResult;
begin
  web := UTF8ToWideString(web);
  form1.ListView1.Items[i].SubItems.strings[4] := web;
  fidHTTP.free;
end;

{Thread ausführen}
procedure TMyThread.Execute;
begin
  i := x;
  fIdHTTP := TIdHTTP.Create(nil);
  web := fIdHTTP.get(form1.ListView1.Items[i].SubItems.Strings[4]);
  Synchronize(GetResult);
end;

{Je Zeile innerhalb der Listview wird ein Thread gestartet}
for x := 0 to listview1.Items.count-1 do
begin
  inc(threadcount);
  MyThread := TmyThread.create(true);
  MyThread.freeonterminate := true;
  mythread.Resume;
  sleep(10);
  application.ProcessMessages;
end;
Das wars auch schon.

Man beachte die application.processmessages in der Aufrufschleife. Wenn diese weggelassen wird, kommt es wieder zu den genannten Fehlern (..Time out...).

Wer kann erklären, warum das so ist?

Viele Grüße und nochmals Danke für die Hilfe

Andreas

marabu 9. Feb 2007 08:24

Re: Laden von HTML-Seiten mit Multithread
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Andreas,

Zitat:

Zitat von Gravitar
... Man beachte die application.processmessages in der Aufrufschleife. Wenn diese weggelassen wird, kommt es wieder zu den genannten Fehlern (..Time out...). Wer kann erklären, warum das so ist? ...

durch die Verwendung von Synchronize() wartet das Programm auf den Eintritt des VCL MainThread in die Idle-Routine. Ohne Application.ProcessMessages() passiert das frühestens nach dem Verlassen deiner Schleife.

Deine Klasse TMyThread könnte ich mir auch ohne die feste Kopplung an die Benutzerschnittstelle vorstellen. Der Code im Anhang ist allerdings nicht getestet.

Grüße vom marabu

Gravitar 9. Feb 2007 10:40

Re: Laden von HTML-Seiten mit Multithread
 
Hallo Marabu,

Zitat:

Zitat von marabu
durch die Verwendung von Synchronize() wartet das Programm auf den Eintritt des VCL MainThread in die Idle-Routine. Ohne Application.ProcessMessages() passiert das frühestens nach dem Verlassen deiner Schleife.

Aha, aber warum wird dann der Fehler zurückgemeldet? :gruebel: Nach Verlassen der Schleife wäre das doch auch o.k.

Zitat:

Zitat von marabu
Deine Klasse TMyThread könnte ich mir auch ohne die feste Kopplung an die Benutzerschnittstelle vorstellen. Der Code im Anhang ist allerdings nicht getestet.

Oh, fein. Ich schau mir das mal an und probiere es heute Abend aus. Danke für den Source (das Thema constructor scheint eine Antwort auf meinen ersten Eintrag zu sein (Parameterübergabe) :-D

Gruß, Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:47 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz