![]() |
IDHttp und Thread
Hallo...
Mein Problem ist folgendes: Ich habe ein Stringgrid in dem in einer Spalte Domainnamen stehen die ich mit IdHttp überprüfen will. Würde das auch gerne mit mittels Threads tun.
Code:
Klar, die Spalte des Stringgrids müßte erstmal in eine Tstringlist umgewandelt werden.
URL := 'http://www.whois.net/whois_new.cgi?d='+Form1.StringGrid1.Cells[1, Form1.StringGrid1.Row];
Nur wie realisiere ich das Abfragen über die Threads? Habe diese Beispiel gefunden und bin zur Zeit damit am rumprobieren. Leider funktioniert überhaupt nichts, deshalb hier das gefundene Beispiel: TBackgroundDownloaderUnit
Code:
Ein kleines Demo-Programm zum Testen:
unit TBackgroundDownloaderUnit;
interface uses Classes, Windows, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP; type TReplyReceivedEvent = procedure (URL, Reply: string) of object; TBackgroundDownloader = class (TThread) URL, Reply : string; OnReplyReceived : TReplyReceivedEvent; IdHTTP : TIdHTTP; constructor Create (CreateSuspended: boolean); procedure CallUserEvent; procedure Execute; override; end; implementation constructor TBackgroundDownloader.Create(CreateSuspended: boolean); begin inherited; IdHTTP := TIdHTTP.Create(nil); end; procedure TBackgroundDownloader.CallUserEvent; begin if Assigned(OnReplyReceived) then OnReplyReceived (URL,Reply); end; procedure TBackgroundDownloader.Execute; begin Reply := IdHTTP.Get (URL); Synchronize (CallUserEvent); IdHTTP.Free; IdHTTP := nil; end; end.
Code:
Welche Möglichkeiten habe ich?unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } procedure IrgendeinName(URL,Reply: string); end; var Form1: TForm1; implementation uses TBackgroundDownloaderUnit; {$R *.DFM} procedure TForm1.IrgendeinName(URL,Reply: string); begin MessageDlg ('Von der URL'#13#10+URL+#13#10+'kam folgendes zurück:'#13#10#13#10+Reply, mtInformation, [mbOk], 0); end; procedure TForm1.Button1Click(Sender: TObject); begin with TBackgroundDownloader.Create (true) do begin URL := 'http://www.quellcodes.de/'; OnReplyReceived := IrgendeinName; Resume; end; end; end. Grüße Aaron |
Re: IDHttp und Thread
Zitat:
_______________________________ Eine TThread-Instanz ist ein Objekt, das in der "Execute"-Methode parallel zum Hauptprogramm (welches in einem eigenen Thread läuft) irgendwelche Anweisungen abarbeitet. Wenn nun zwei verschiedene Threads auf ein gemeinsames Datum (z.B. einen String) zugreifen müssen, kann es dazu kommen, dass ein Datum gleichzeitig gelesen und geschrieben wird. Dadurch wird der Wert des Datums unbestimmt und es kommt zu ![]() Um das zu verhindern, müssen Zugriffe auf gemeinsame Daten synchronisiert werden. Man muss irgendwie dafür sorgen, dass das Datum, auf das man zugreift, konsistent ist. Eine einfache Methode dafür sind synchronisierte ![]() Ruft also ein Thread ein Ereignis mit der Methode ![]() ![]() _______________________________ Also wo hakt es denn? Ist das ganze Konzept mit Klassen, Ereignissen usw. schon klar? Hast du schonmal Luckies Thread-Tutorial durchgelesen? Edit: du kannst für mehr Lesbarkeit Delphi-Code mit dem [Delphi]-Tag anstelle des [Code] Tags markieren |
Re: IDHttp und Thread
Hallo Dani,
danke für deine ausführliche Erklärungen. Es hakt bei den Abfragen per IdHttp mit Threads. Ich habe mich noch nicht viel mit Threads beschäftigt, Klassen und Ereignisse sind für mich keine absoluten Fremdwörter. Ich sehe mich aber eher als Anfänger, obwohl ich nicht ganz bei Null anfange. Das Tutorial von Lucky bin ich gerade am lesen. Ich bin auch nur auf Threads gekommen weil ich in diesem von mir begonnenen "Thread" darauf hingewiesen worden bin, dass das was ich vorhabe nur mit Threads zu lösen ist: ![]() Freundliche Grüße Aaron [EDIT]Ist das was ich vorhabe sehr kompliziert? |
Re: IDHttp und Thread
Zitat:
Zitat:
Delphi-Quellcode:
Bitte daran denken, dass dieser Code nicht zum kopieren und einfügen gedacht ist, sondern nur zum Verständnis beitragen soll. Mit dieser Klasse haben wir also schonmal die Ein- und Ausgaben der Aufgabe modelliert. Es fehlt aber noch der Vorgang, wo ermittelt wird, ob die Domain existiert (übrigens würde ich für die reine Namensauflösung lieber IdDNSResolver nehmen). Also:
type
TDomainAbfrageErgebnis = (daUnbekannt, daExistiert, daExistiertNicht); TDomainAbfrage = class(TObject) private FDomain: String; FErgebnis: TDomainAbfrageErgebnis; public constructor Create(Domain: String); property Domain: String read FDomain write FDomain; property Ergebnis: TDomainAbfrageErgebnis read FErgebnis; end;
Delphi-Quellcode:
Jetzt ist unser Modell in der Lage, das Ergebnis einer DNS-Abfrage zu ermitteln. Aber wo ist der Thread? Irgendwo im Programm muss ja die Methode "Durchfuehren" einer TDomainAbfrage-Instanz aufgerufen werden. Dafür ist der "Arbeiter-Thread" zuständig:
type
TDomainAbfrageErgebnis = (daUnbekannt, daExistiert, daExistiertNicht); TDomainAbfrage = class(TObject) private FDomain: String; FErgebnis: TDomainAbfrageErgebnis; public constructor Create(Domain: String); procedure Durchfuehren; property Domain: String read FDomain write FDomain; property Ergebnis: TDomainAbfrageErgebnis read FErgebnis; end; {...} procedure TDomainAbfrage.Durchfuehren; var DNSResolver: TIdDNSResolver; begin DNSResolver := TIdDNSResolver.Create; try // Oder wie auch immer TIdDNSResolver funktioniert...das überlasse ich mal dir :) // Indy-Exceptions abfangen nicht vergessen! case DNSResolver.Resolve(FDomain) of Jawohl: FErgebnis := daExistiert; Neeein: FErgebnis := daExistiertNicht; Fehler: FErgebnis := dsUnbekannt; end; finally DNSResolver.Free; end; end;
Delphi-Quellcode:
Was man hier nicht sieht: du musst natürlich irgendwo im Programm eine Liste von Threads und eine Liste von Aufgaben verwalten, mit den erwähnten Tücken beim gemeinsamen Zugriff!
type
TArbeiterThread = class(TThread) private FAktuelleAufgabe: TDomainAbfrage; protected procedure Execute; override; end; implementation procedure TArbeiterThread.Execute; begin // Pseudocode: // "Endlosschleife", welche so lange DNS-Aufgaben abarbeitet, bis keine // Aufgaben mehr übrig sind. while not Termiated do begin Synchronize(HoleNächsteAufgabe); if AufgabeWurdeGeholt then begin FAktuelleAufgabe.Durchführen; end; end; end; So, jetzt hab ich mal einen konkreten Lösungsansatz angerissen. Hast du dazu noch irgendwelche Fragen? Falls nicht, kannst du dir noch ![]() |
Re: IDHttp und Thread
HAllo Dani,
vielen...vielen Dank für deine Beispiele. Ich möchte nicht nur den Domainnamen abfragen sondern noch mehr, also brauche ich den ganzen Quelltext, ich kann dein Beispiel so nicht adaptieren. Trotzdem nochmal vielen Dank. Aaron |
Re: IDHttp und Thread
Eigentlich wollte ich dir nie ein funktionierendes Beispiel liefern. Die Hoffnung war, dass du die grundsätzliche Idee aufschnappst und quasi als mündiger, Threads-benutzender Programmierer aus diesem Thema hervorgehst ( :mrgreen: ). Ich kann aber auch eine funktionierende Lösung basteln und hier reinstellen, wenn dir das lieber ist. :|
Dazu müsste ich aber wissen, was genau du meinst mit: Zitat:
|
Re: IDHttp und Thread
Zitat:
Zitat:
Delphi-Quellcode:
verwendet.
IdHttp1.get('http://www.whois.net/whois_new.cgi?d='+Form1.StringGrid1.Cells[1, Form1.StringGrid1.Row];
Ich durchsuche dann immer den Quelltext nach einem bestimmten Wort, wenn dieses Wort gefunden wird dann soll in das Stringgrid ein "Ja" geschrieben werden andernfalls ein "Nein". Nochmal Danke! Freundliche Grüße Aaron |
Re: IDHttp und Thread
Liste der Anhänge anzeigen (Anzahl: 1)
Nach dem Wort suchen musst du selbst (in TWhoisLookupJob.Execute) :P
|
Re: IDHttp und Thread
Hallo Dani
Wahnsinn, das hätte ich so schnell nicht hinbekommen auch nicht in den nächsten Monaten. Danke. Freundliche Grüße Aaron |
Re: IDHttp und Thread
Hallo Dani,
zwei "kleine" Fragen habe ich doch noch. :shock: Wo ich die Threadgeschwindigkeit steuern, ist das überhaupt möglich? Wäre das dazu die richtige Stelle für ein IDHttp.Timeout?
Delphi-Quellcode:
Viele Grüße
try
HTTP.HandleRedirects := true; try FReply := HTTP.Get(Format(WHOIS_LOOKUP_FORMATSTR, [FURL])); FSuccess := true; HTTP.ConnectTimeout:=1500; except Aaron |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz