Einzelnen Beitrag anzeigen

Votum

Registriert seit: 27. Mai 2010
3 Beiträge
 
#1

Threads die wieder andere Threads aufrufen in einer schleife

  Alt 27. Mai 2010, 15:33
Hallo Liebe Community, meine erster Post hier aber ich hoffe ihr helfft mir trotzdem.

Ich versuche seid gestern einen Webcrawler zu schreiben. Dieser soll Links ausgeben und in eine Listbox ausgeben. Das klappt auch supper. Da er aber auch die unterebenen durchsuchen soll, erstelle ich für jeden Link einen weiteren Thread der die Links der 2 ebene Parst und überprüft ob diese schon in der Listbox vorhanden sind.Danach soll es weiter zur 3. Ebene gehen. Also erstellt der Thread sich rekursiv weiter. So lange bis er keine neuen Links mehr findet.

Mein Problem: Ab 150 Threads wird entweder das Programm grottig langsam oder die Page geht down.

Daher will ich die Anzahl der Threads begrenzen. Leider ist das nicht so einfach da ich ja nicht eifnach sagen kann so stop da es sonst ein Deadlock gibt.

Hat jemand eine Idee?


Hier noch mein bisheriger Quellcode:

Delphi-Quellcode:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, JvComponentBase, StdCtrls, idhttp, strutils;




type
  THTTPThread = class(TThread)
  private
    FURL: String;
    HTTP: tidhttp;
    FListText: String;
  protected
    procedure DoWriteListBox;
    procedure DoUpdateThreadCount;
  public
    procedure Execute; override;
    constructor Create(URL: String);
    destructor Destroy; override;
  published
    property URL: String read FURL;
  end;

  TArrayofstring = array of string;
  TForm3 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ListBox1: TListBox;
    Memo1: TMemo;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


var
  Form3: TForm3;
  host:string;
  ccount: integer = 0;

implementation

{$R *.dfm}

constructor THTTPThread.Create(URL: String);
begin
  inherited Create(true);
  FreeOnTerminate := true;
  FURL := URL;
  Resume;
end;


function FindInString(Text, SearchFrom, SearchTo: string; FirstOnly: Boolean; var Return: TArrayOfString): Boolean;
var
  i: Integer;
  FoundString: string;
begin
  Result := False;
  SetLength(Return, 0);
  i := Pos(SearchFrom, Text);
  while i > 0 do
  begin
    Result := True;
    i := i + Length(SearchFrom);
    FoundString := Copy(Text, i, PosEx(SearchTo, Text, i) - i);
    SetLength(Return, Length(Return) + 1);
    Return[High(Return)] := FoundString;
    Delete(Text, 1, i);
    i := Pos(SearchFrom, Text);
    if FirstOnly then
      Break;
  end;
end;



procedure TForm3.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  host := edit1.Text;
  THTTPThread.Create(host);
end;




destructor THTTPThread.Destroy;
begin
  inherited;
end;

procedure THTTPThread.DoUpdateThreadCount;
begin
  Form3.label1.Caption := IntToStr(CCount);
end;

procedure THTTPThread.DoWriteListBox;
begin
  Form3.ListBox1.Items.Add(FListText);
end;

procedure THTTPThread.Execute;
  var
i, j,x,position:integer ;
http:tidhttp;
links:tarrayofstring;
s: string;
found: boolean;
begin

inc(ccount);
synchronize(DoUpdateThreadCount);

HTTP := TIdHTTP.Create(nil);
http.HandleRedirects:= true;
try
  s := http.Get(URL);
except
  S := '';
end;

   findinstring(s,'href="','"',false,links);
   for I := 0 to High(Links) do
   begin
        FListText := links[i];
           if Copy(FListText, 1, 4) <> 'httpthen
            begin

              FListText := host + FListText;

              // und hier mit nem if oder ?
              found := false;
              for j := 0 to form3.ListBox1.items.count -1 do
              begin
                if form3.listbox1.items[j] = FListText then
                begin
                  found := true;
                  break;
                end;
              end;
              if not found then
              begin
              THTTPThread.Create(FListText);
              Synchronize(DoWriteListBox);
              end;
            end else if Pos(Host, FListText) > 0 then
            begin
              found := false;
              for j := 0 to form3.ListBox1.items.count -1 do
              begin
                if form3.listbox1.items[j] = FListText then
                begin
                  found := true;
                  break;
                end;
              end;
              if not found then
              begin
              THTTPThread.Create(FListText);
              Synchronize(DoWriteListBox);
              end;
            end;



   end;
   dec(ccount);
synchronize(DoUpdateThreadCount);
end;
  Mit Zitat antworten Zitat