Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - THread.Execute


sPeeD2k5 - Fr 05.09.08 13:11
Titel: THread.Execute

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TMyOwnThread.Execute;
var
  idhttp1:TIDhttp;
  schleife1,schleife2:integer;
  aurl:string;

//  ip,pfad,results : TStringlist;
begin

  try
  begin
  for i:= 0 to ip.Count-1 do
    for j:= 0 to pfad.Count-1 do

    ishttpsourcethere(i,j);
    results.add(inttostr(code));

    Synchronize(SyncBinFertig);


Folgendes Problem: Ich kann meine Funktion ishttpsourcethere nicht mit den Variablen i und j aufrufen... wenn ich stattdessen 0,0 benutze funktioniert es.. Ich kann mir einfach nicht erklären warum es mit den Zählvariablen nicht funktioniert... jemand ne ideE?

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Delete - Fr 05.09.08 13:17

Und ich kann mir nicht erklären, was die Funktion ishttpsourcethere macht bzw. wo i und j überhaupt deklariert sind.


sPeeD2k5 - Fr 05.09.08 13:19


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function TMyOwnThread.isHTTPSourceThere(a,b:integer): Integer;
var
  idhttp1:TIDhttp;
  aurl:string;
begin

  //writeln(ip[i]);
  //writeln(pfad[i]);
 {  i:=0;
  j:=0;    }


  idhttp1 := Tidhttp.Create(nil);
  idhttp1.ReadTimeout:=1000;
  idhttp1.ConnectTimeout:=1000;
  AURL:='http://'+IP[a]+Pfad[b];
  with IdHTTP1 do
  begin
    try
      Response.Clear;
      HEAD(AURL);
    except
    end;
    Result := IdHTTP1.ResponseCode;
    code:= IdHTTP1.ResponseCode;
  end;
  idhttp1.Free;
end;


I und J sind als globale variablen deklariert...

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


BenBE - Fr 05.09.08 13:24

Könntest Du bitte Delphi-Tags für deine Sources verwenden, so wie es user profile iconNarses so schön für dich immer nachholt?

Erstmal zum Code:
- Zählvariablen gehören NICHT global
- In Proceduren ist kein Result vorhanden
- Könntest Du bitte "funktioniert nicht" etwas genauer definieren?


Delete - Fr 05.09.08 13:26

user profile iconsPeeD2k5 hat folgendes geschrieben:
I und J sind als globale variablen deklariert...

Hast du dir die Warnung vom Compiler diesbezüglich mal durchgelesen?


sPeeD2k5 - Fr 05.09.08 13:35

ja ich habe sie jetzt nicht mehr als globale variablen.. das ändert aber nix an meinem problem... Ich bekomme immer die Fehlermeldung ReadTimeout... Also er erhält als Responsecode noch 200 OK und an der Stelle kommt dann "Readtimeout blabla"


BenBE - Fr 05.09.08 13:58

Viele Server sind relativ langsam. Teilweise kann es durchaus2-3 Sekunden dauern, biss man eine Antwort bekommt. Änder dein Timeout mal auf 5000 oder 15000.


sPeeD2k5 - Fr 05.09.08 14:35

alles klar jetzt scheints zu funktionieren :) noch eine frage... wie kann ich die aufgaben auf die threads am besten verteileN? also der benutzer soll selber bestimmen können wie viele threads verwendet werden und dementsprechend sollen die abzuarbeitenden ips aufgeteilt werdn


BenBE - Fr 05.09.08 15:04

Erzeug eine globale Liste, wo alle IPs drin stehen (oder IP-Bereiche) ... Und aus dieser Liste liest jeder Thread immer einen Auftrag. und schreibt in einer weiteren Liste sein Ergebnis für diesen Auftrag rein.


sPeeD2k5 - Fr 05.09.08 15:11

ja sowas habe ich auch schon in der richtung gedacht allerdings is mein problem noch, dass die ips dann teilweise doppelt und dreifach abgearbeitet werden... kann man aus einer bestehenden stringlist viele kleine erzeugen?


Delete - Fr 05.09.08 15:52

Wenn in der Liste keine doppelten Einträge vorhanden sind, kannst du die Anzahl der Einträge durch die Anzahl der Threads teilen. Jeder Thread bekommt dann einen Teil der Liste zugeordnet, den er abarbeitet.
Beispiel: 10 Einträge, 5 Threads.
10 : 5 = 2: Jeder Thread bekommt also 2 Einträge
Jetzt zerlegst du die List in fünf kleine Listen mit zwei Einträgen und übergibst jede Liste einem Thread.


sPeeD2k5 - Fr 05.09.08 15:58

ja aber wie zerlegt man eine stringliste in mehrere kleine? am besten mit fortlaufender zählvariabel versehen.


Delete - Fr 05.09.08 16:11

Ein Ansatz:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
const
  ANZAHLSTRINGLISTEN = 5

var
  sl: TStringList;
  slarray: array of TStringList;
  i: Integer;
  AnzahlItems: Integer;

begin
  sl := TStringList.Create;
  for i := 0 to 9 do
    sl.Add(Format('Eintrag %d', [i]));

  AnzahlItems := sl.Count / ANZAHLSTRINGLISTEN;
  Setlength(slarray, anzahl);

  for i := 0 to anzahl - 1 do
  begin
    slarray[i] := TStringList.Create;
    // Arrays füllen
  end;
end;


BenBE - Fr 05.09.08 17:18

Warum nicht einfach eine TCriticalSection nehmen und mit dieser den Zugriff auf die StringList synchronisieren???

Das bietet nicht nur den Vorteil, dass jeder Thread so viel Arbeit machen kann, wie er schafft, ohne dass Dinge doppelt bearbeitet werden, sondern man sogar noch während die Threads arbeiten neue Aufgaben hinzufügen kann.