Avatar billede poulsgaard Praktikant
19. februar 2004 - 12:36 Der er 17 kommentarer og
1 løsning

Flere tråde(objekter

Hej

Jeg skal lave mange (100+) forsp. til en php siden inden for eet minut. jeg forstiller mig jeg kan bruge noget alá idhhtp.get('blabla.pgp?XXX') (det eneste der er forskelligt i mine forsp er XXXX) og vente på svar og dekode mit svar.

Men nu da jeg skal bruge så mange kan jeg jo ikke vente på at webserveren skal svare mig 100 gange, en ventetid på >1 sek vil jo gøre at jeg ikke kan få svar inden for et minut på sidste forsp.

Mit spørgsmål er nu. Kan jeg ikke bare lave et nyt objekt, hver gang jeg vil have en forsp. afsted. Resultatet skal i en DB, det kan jeg gøre i Objektet, inden jeg destructer det ingen.

-og i givet fald:
Kan jeg lave en klasse der som input param tager XXX. og så dynamisk lave det antal klasser der er nødvendigt for at kunne afvikle mine forsp. inden for 1 min.

Eller er jeg helt i skoven.
-i givet fald, HJÆÆÆÆÆÆÆÆLP

Poulsgaard

-På forhånd tak
Avatar billede dkn Nybegynder
19. februar 2004 - 15:36 #1
syntes du skal se på delphi's thread eksempel, hvis du har problemer med det, må du jo vende tilbage.
Avatar billede borrisholt Novice
19. februar 2004 - 16:25 #2
Start med at skrive dig en klasse der kan gøre det du vil ... der er lige et par regler :

1) Den må ikke bruge noget UDEN for sin sig selv. Altså ALT sættes op med properties ude fra, når den bliver lavet!
2)
  Du må ikke i constructoren sætte handlingen i gang ... det skal være en metode for sig selv !!!!

Nå du har det så vend tilbage !!!

Jens B
Avatar billede poulsgaard Praktikant
23. februar 2004 - 14:00 #3
Borrisholt -> Det er gjort.
Avatar billede borrisholt Novice
23. februar 2004 - 14:16 #4
1)
  Din klasse skal arve fra TThread !
2)
  I din constructor
  Skriver du FreeOnTerminate := true
  Det betyder at du ikke den selv nedlægger sigselv når den er færdig.
3)
  Den metode der styrer det hele skal du kalde Execute ..

type
  THest = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure THest.Execute;
begin
  Hest skal du udføre alt dit kode ....
  DU MÅ IKKE KALDE INHERITED.
  Når denne procedure er færdig TERMINERER din tråd !!
end;

Prøv det ...

Jens B
Avatar billede poulsgaard Praktikant
23. februar 2004 - 14:50 #5
"DU MÅ IKKE KALDE INHERITED."´

Jeg går ud fra at min constructor skal hedde:

procedure TGetPlayer.Create(CreateSuspended: Boolean );
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
end;

Eller hvordan ??
Avatar billede borrisholt Novice
24. februar 2004 - 09:30 #6
Korrekt det var i Execute du ikke måtte kalde ineherited :o)

Jens B
Avatar billede poulsgaard Praktikant
24. februar 2004 - 09:41 #7
Jeg har lavet en constructor der hedder:
procedure TGetPlayer.Create(CreateSuspended: Boolean );
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
end;

Jeg har i min "main" lavet en stringlist med alle de "XXX" jeg ønsker at kalde.

Det jeg gør nu er:

for index:=0 to count do begin     
  Memo1.Lines.Objects[index] := TGetplayer.create(FALSE);
  (Memo1.Lines.Objects[index] as TGetplayer).PlayerIDnr:= ADOQuery1['xxx'];
end;

Men når jeg skriver til PlayerIDnr i min tråd får jeg enfejl (47): This form of method call only allowed for class methods ???

Peder Poulsgaard
Avatar billede borrisholt Novice
24. februar 2004 - 09:44 #8
din forsætning skal flyttes ned i Execute.

Nå så du oprettet din trån, sætter du den op, og så kander du Resume og så kalder tråden SELV execute

Jens B
Avatar billede poulsgaard Praktikant
24. februar 2004 - 09:49 #9
Jeg har en form med en knap, det er min "main" form (Tform1). Der er her jeg forstillede mig at jeg skulle oprette et antal tråde af min klasse TGetPlayer.

Min for-løkke der skal oprette det antal tråde jeg nu har brug for skal vel ikke ligge i en tråd?

Eller er jeg helt gal på den ?

Poulsgaard
Avatar billede poulsgaard Praktikant
24. februar 2004 - 09:57 #10
Sorry det er allerede når jeg i min TForm1 forsøger at create en instans af min klasse TGetPlayer (som har arvet fra TThread) at min fejl kommer. Denne fejl er først kommet efter jeg har ændret i constructoren i TGetPlayer, før fik jeg en fejl (access violation) når jeg forsøgte at skrive til min property (PlayerIDnr) i min instans af TGetplayer
Avatar billede borrisholt Novice
24. februar 2004 - 10:19 #11
Lad mig se projektet !

Jens B
Avatar billede poulsgaard Praktikant
24. februar 2004 - 11:00 #12
Jeg har klippet lidt i det, håber du kan se det du skal....


program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
----------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, ADODB;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
index: integer;
begin

  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from ppo where State = 0');
  ADOQuery1.Active:=TRUE;
  for index:= 0 to ADOQuery1.RecordCount-1 do
      begin
      Memo1.Lines.Add(inttostr(ADOQuery1['playerID']));
      Memo1.Lines.Objects[index] := TGetplayer.create(FALSE);
      (Memo1.Lines.Objects[index] as TGetplayer).PlayerIDnr:= ADOQuery1['playerID'];
    end;

end;

end.


----------------------------------------------------------------

unit Unit2;

interface

uses
  Classes, sysutils, ADODB, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP;

type
  TGetPlayer = class(TThread)
  private
      LokalPlayerID: integer;
      Deadline: String;
      procedure SetPlayerID(const Value: integer);
     
    { Private declarations }
  protected
      procedure Execute; override;
  public
      property  PlayerIDnr: integer read LokalPlayerID write SetPlayerID;
      procedure Create(CreateSuspended: Boolean );
  end;


implementation

procedure TGetPlayer.Execute;
var
  cookiestr: string;
  Outint: integer;
  IdHTTP1: TIdHTTP;
  ADOConnection1: TADOConnection;
  ADOQuery1: TADOQuery;

const SQL_updatestr = '.....';


begin
  IdHTTP1:= TIdHTTP.Create(nil);
  ADOConnection1 := TADOConnection.Create(nil);
  ADOQuery1 := TADOQuery.Create(nil);

  ADOConnection1.ConnectionString:='...';
  ADOConnection1.LoginPrompt:=FALSE;

  ADOQuery1.Connection:=ADOConnection1;


  DecimalSeparator:='.';
  IdHTTP1.Get('.......');
  cookiestr:=fragstring(idhttp1.Response.ExtraHeaders.Strings[0],5,61);
  idHTTP1.Request.ExtraHeaders.Add(cookiestr);
  Outint:= Hentspillerparam(IdHTTP1.Get(format('.....%d',[LokalPlayerID])));
  if  Outint >= 20 then
  begin
      ADOConnection1.Connected:=TRUE;
      ADOQuery1.SQl.Clear;
      ADOQuery1.SQL.Add(format(....));
      ADOQuery1.ExecSQL;
      ADOConnection1.Connected:=FALSE;
  end
  else
  begin
      ADOConnection1.Connected:=TRUE;
      ADOQuery1.SQl.Clear;
      ADOQuery1.SQL.Add(format('....');
      ADOQuery1.ExecSQL;
      ADOConnection1.Connected:=FALSE;
  end;



  IdHTTP1.Request.ExtraHeaders.Clear;
  ADOConnection1.Free;
  ADOQuery1.Free;
  IdHTTP1.Free;
end;


procedure TGetPlayer.SetPlayerID(const Value: integer);
begin
  LokalPlayerID:=Value;
end;
Avatar billede poulsgaard Praktikant
24. februar 2004 - 11:03 #13
Og så constructoren til Unit2

procedure TGetPlayer.Create(CreateSuspended: Boolean );
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
end;
Avatar billede borrisholt Novice
24. februar 2004 - 11:04 #14
Hurtigt gæt :
procedure TForm1.Button1Click(Sender: TObject);
var
index: integer;
begin

  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from ppo where State = 0');
  ADOQuery1.Active:=TRUE;
  for index:= 0 to ADOQuery1.RecordCount-1 do
      begin
      Memo1.Lines.Add(inttostr(ADOQuery1['playerID']));
      Memo1.Lines.Objects[index] := TGetplayer.create(TRUE);
      with (Memo1.Lines.Objects[index] as TGetplayer) do
      begin
        PlayerIDnr:= ADOQuery1['playerID'];
        Resume;
      end;
    end;
end;


Jens B
Avatar billede poulsgaard Praktikant
24. februar 2004 - 11:07 #15
Men allerede når jeg kompiler får jeg en: (47): This form of method call only allowed for class methods ???

Det har jeg gjort siden jeg har ændret i construstoren i TGetPlayer
Avatar billede poulsgaard Praktikant
24. februar 2004 - 12:31 #16
Arhhh... "Jeg er Benny"....

en constructor hedder:
constructor TGetPlayer.Create(CreateSuspended: Boolean );
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
end;

Det hjalp på min fejl 47.....

Men når jeg stepper igennem koden er der ved linien der skriver til min property der kommer en Access violation.

Lige på : LokalPlayerID:=Value;
Avatar billede poulsgaard Praktikant
24. februar 2004 - 13:36 #17
Jens B

Jeg har lavet et nyt projekt der kun lige koncentrere sig om denne Access Violation må jeg maile dette projekt til dig ? (Og andre der måtte ønske det) Så kan du prøve at køre det lokalt.
Avatar billede poulsgaard Praktikant
24. februar 2004 - 13:50 #18
Det ser ud at til det ikke er tilladt at linke imellem Memo'er og tråde..

Hvis jeg istedet anvender TStringlist har jeg ikke noget problem.

Jeg lukker og slukker.

Tak for hjælpen Jens B
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester