Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Die erste Thread-Programmierung... (https://www.delphipraxis.net/11097-die-erste-thread-programmierung.html)

Lefko 30. Okt 2003 23:19


Die erste Thread-Programmierung...
 
Hallo Freunde, :hi:

ich hab mich grad das erste mal an threads rangewagt und mir dazu ein threadtutorial durchgelesen, das anhand der Thread-demo bei borland einige funktionen etc. erklärt.
Nu will ich einen thread schreiben, der den befehl URLDownloadToFile ausführt (die Form ist sonst immer so ewig lang nicht "ansprechbar" und sieht aus wie abgestürzt...) und dabei einige Parameter aus der Form1 verwendet!

da ich wie gesagt noch überhaupt keine ahnung davon hab, weiss ich auch nicht, was an meinem text so unglaublich falsch ist, ich hab probiert, es getreu dem beispiel zu machen!

hier der text, ich wäre dankbar, wenn ihr mir die fehler erklärtet!

Delphi-Quellcode:
unit ThreadUnit;

interface

uses
  UrlMon, StdCtrls, ExtCtrls, Windows, SysUtils, Classes, Dialogs, Controls;

type
  TDownloadThread = class(TThread)
  private
       { Private declarations }
     BILDNAME,                          //
     URL_TEIL1,                         //
     URL_TEIL2,                         //Das sind die Texte von 5 LabeledEdits aus der Form1.
     VERZEICHNIS : string;              //Sie sollen im Thread verwendet werden (also müssen sie
     ANZAHL : integer;                  //übergeben werden (in Thread.Create), richtig?)
     procedure UpdateForm1;            
  protected
     procedure Execute; override;
     procedure DownloadFile;
  public
       { Public declarations }
     constructor Create(LEdit1,LEdit2,LEdit3,LEdit4,LEdit5 : TLabeledEdit); //stimmt das?
    end;

implementation

var z : integer;

{ Important: Methods and properties of objects in VCL or CLX can only be used
  in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TDownloadThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ TDownloadThread }

procedure TDownloadThread.UpdateForm1; //wie im obigen Standard-Beispiel!
begin
Form1.Label1.caption := 'Datei ' + IntToStr(z) + ' von ' + IntToStr(ANZAHL) + ' fertig.'; //geht nicht!
end;


procedure DownloadFiles;
var URL, ORT : string;
begin
z := 1;

if ForceDirectories(Verzeichnis) then
while z <= ANZAHL do begin                                                //hier kennt Delphi die
                     URL := URL_TEIL1 + InttoStr(z) + URL_TEIL2;          //BEZEICHNER nie!
                     ORT := VERZEICHNIS + BILDNAME + IntToStr(z) + '.jpg'; //weshalb? wo müssen sie
                                                                           //deklariert werden?                                                UrlDownloadtoFile(nil, PCHAR(URL), PCHAR(ORT), 0, nil);//sollen ja aus der
                                                                           //Form1 kommen (Edits)

                     Synchronize(UpdateForm1); //hab ich nach dem obigen Standard-Beispiel gemacht!
                     inc(z);
                     end;
end;



constructor TDownloadThread.Create(LEdit1, LEdit2, LEdit3, LEdit4, LEdit5 : TLabeledEdit);
begin
URL_TEIL1 := LEdit1.text;           //Kann man das hier so zuordnen?!
URL_TEIL2 := LEdit2.text;
ANZAHL := StrToInt(LEdit3.text);    //Es sollen eine best. Anzahl Bilder gedownloadet werden
VERZEICHNIS := LEdit4.text;          
BILDNAME := LEdit5.text;            //Benennung der geladenen Bilder (+fortlaufende Nr.)
FreeOnTerminate := True;
end;



procedure TDownloadThread.Execute;
begin
  { Place thread code here }
DownloadFiles;
end;

end.


...


// so wird der Thread generiert (in Unit1):

TDownloadThread.Create(LabeledEdit1,
                       LabeledEdit2,
                       LabeledEdit3,
                       LabeledEdit4,
                       LabeledEdit5 : TLabeledEdit);

MfG Lefko. :balloon:

Christian Seehase 30. Okt 2003 23:34

Re: Die erste Thread-Programmierung...
 
Moin Lefko,

als erstes solltest Du besser direkt die Inhalte der Edits übergeben nicht die Edits selber.
Nur so als Idee: Bau Dir einen Record Typ für die Inhalte, und übergib dann einfach eine Variable dieses Typs

Der Thread dürfte übrigens niemals starten, da der Konstruktor von TThread nie aufgerufen wird.
Dazu müsstest Du im Deinem Konstrukur, am Ende inherited Create(true oder false) aufrufen. Vermutlich macht hier false Sinn, damit der Thread gleich startet.

Die Prozedur DownloadFiles ist keine Methode von TDownloadThread, deshalb kennt Delphi die Bezeichner da nicht.
Die muss genauso Methode der Klasse sein, wie DownloadFile.

Lefko 31. Okt 2003 17:12

Re: Die erste Thread-Programmierung...
 
Hi!

ich hab das mal verbessert wie du, christian, gesagt hast!
aber es klappt immer noch nicht! delphi kennt den bezeichner "Form1" nicht in UpdateForm1!
in dem standardbeispiel wird aber doch auch Form1.caption geupdatet mit Synchronize?!
wo ist da der fehler?

Delphi-Quellcode:
//hier sagt er immer "Missing operator or semicolon" und "Undeclared identifier 'Form1' " ?!

procedure TDownloadThread.UpdateForm1;
begin
//hier sagt delphi immer "Missing operator or semicolon" und "Undeclared identifier 'Form1' " ?!

Form1.Label1.caption := 'Datei ' + IntToStr(z) + ' von ' + IntToStr(ANZAHL) + ' fertig.';
end;
ich weiss nich, wieso das nich geht, deswegen bin ich auch eure hilfe angewiesen!

MfG Lefko :wall:

supermuckl 31. Okt 2003 18:33

Re: Die erste Thread-Programmierung...
 
du must das form1 noch in die uses schreiben der threadunit

Lefko 31. Okt 2003 19:08

Re: Die erste Thread-Programmierung...
 
Zitat:

Zitat von supermuckl
du musst das form1 noch in die uses schreiben der threadunit

wenn ich das in die uses schreibe, kommt "File not found: Form1.dcu" .

dazu hab ich auch generell ne frage, was haben die dcu s für ne funktion und wie generiert man sie?
also wie kann ich denn jetzt form1 in diese threadunit mit einbeziehen?


Mfg Und danke :)Lefko

supermuckl 31. Okt 2003 19:23

Re: Die erste Thread-Programmierung...
 
ups ich meinte eigentlich unit1
also so wie die threadunit in der hauptunit eingetragen is muss es auch anderstrum sein damit man in der threadunit auch weis was form1 bedeutet :)

scp 31. Okt 2003 22:12

Re: Die erste Thread-Programmierung...
 
Foldender Vorsachlag:

Delphi-Quellcode:
unit ThreadUnit;

interface

uses
  UrlMon, StdCtrls, ExtCtrls, Windows, SysUtils, Classes, Dialogs, Controls;

type
  TDownloadThread = class(TThread)
  private
       { Private declarations } 
     FStatusLabel : TLabel;
     BILDNAME,                          //
     URL_TEIL1,                         //
     URL_TEIL2,                         //Das sind die Texte von 5 LabeledEdits aus der Form1.
     VERZEICHNIS : TLabeledEdit;              //Sie sollen im Thread verwendet werden (also müssen sie
     ANZAHL : integer;                  //übergeben werden (in Thread.Create), richtig?)
     procedure UpdateForm1;
  protected
     procedure Execute; override;
     procedure DownloadFiles;
  public
     { Public declarations }

     constructor Create(LEdit1,LEdit2,LEdit3,LEdit4,LEdit5 : TLabeledEdit; StatusLabel: TLabel); //stimmt das?
    end;

implementation

var
  z : integer;

{ Important: Methods and properties of objects in VCL or CLX can only be used
  in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TDownloadThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; } 

{ TDownloadThread } 

procedure TDownloadThread.UpdateForm1; //wie im obigen Standard-Beispiel! 
begin
  FStatusLabel.Caption := 'Datei ' + IntToStr(z) + ' von ' + IntToStr(ANZAHL) + ' fertig.'; //geht so
end;


procedure TDownloadThread.DownloadFiles; // Hier hast du nur das TDownloadThread. vergessen, deswegen die Bezeichner-Fehler

var URL, ORT : string;
begin
z := 1;

if ForceDirectories(Verzeichnis.Text) then
while z <= ANZAHL do begin                                                //hier kennt Delphi die
                     URL := URL_TEIL1.Text + InttoStr(z) + URL_TEIL2.Text;          //BEZEICHNER nie!
                     ORT := VERZEICHNIS.Text + BILDNAME.Text + IntToStr(z) + '.jpg'; //weshalb? wo müssen sie
                                                                           //deklariert werden?
                     UrlDownloadtoFile(nil, PCHAR(URL), PCHAR(ORT), 0, nil);//sollen ja aus der
                                                                           //Form1 kommen (Edits)

                     Synchronize(UpdateForm1); //hab ich nach dem obigen Standard-Beispiel gemacht! 
                     inc(z);
                     end;
end;



constructor TDownloadThread.Create(LEdit1, LEdit2, LEdit3, LEdit4, LEdit5 : TLabeledEdit; StatusLabel: TLabel);
begin
  inherited Create(false);
 
  URL_TEIL1 := LEdit1;           //Kann man das hier so zuordnen?!
  URL_TEIL2 := LEdit2;
  ANZAHL := StrToInt(LEdit3.Text);    //Es sollen eine best. Anzahl Bilder gedownloadet werden
  VERZEICHNIS := LEdit4;
  BILDNAME := LEdit5;            //Benennung der geladenen Bilder (+fortlaufende Nr.)
  FStatusLabel := StatusLabel;   // Hier wird quasi ein Pointer auf Form1.Label1 erstellt
  FreeOnTerminate := True;
end;



procedure TDownloadThread.Execute;
begin
  { Place thread code here } 
  DownloadFiles;
end;

end.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ThreadUnit;

type
  TForm1 = class(TForm)
    Button1: TButton;
    LabeledEdit1: TLabeledEdit;
    LabeledEdit2: TLabeledEdit;
    LabeledEdit3: TLabeledEdit;
    LabeledEdit4: TLabeledEdit;
    LabeledEdit5: TLabeledEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  DownloadThread : TDownloadThread;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
// so wird der Thread generiert (in Unit1):

DownloadThread := TDownloadThread.Create(
                       LabeledEdit1,
                       LabeledEdit2,
                       LabeledEdit3,
                       LabeledEdit4,
                       LabeledEdit5,
                       Label1);

end;

end.
Habe dabei keine Syntax-Fehler bekommen, das ausführen des Threads klappt auch.

[edit]
Sorry, waren ein paar Flüchtigkeitsfehler drin.
[/edit]

Lefko 1. Nov 2003 15:18

Re: Die erste Thread-Programmierung...
 
Hi ! ich habdas jetzt gelöst, das downloaden klappt auch!
aber das updaten des labels in form1 geht nicht, das label bleibt leer, aber es kommt auch kein fehler!

was kann das bedueten?

MfGLefko.

scp 1. Nov 2003 15:44

Re: Die erste Thread-Programmierung...
 
Hmmmm... wenn du denn Code so wie oben geschrieben hast müsste es eigentlich klappen, bei mir ändert sich jedenfalls die Caption. Habe übrigens auch D6E.
Wichtig ist
Delphi-Quellcode:
Synchronize(UpdateForm1);
und das die Caption des Label nur in der Prozedur
Delphi-Quellcode:
TDownloadThread.UpdateForm1;
geändert werden kann.

Lefko 1. Nov 2003 16:06

Re: Die erste Thread-Programmierung...
 
Ja, du hast recht :D

ich hab einfach nicht lang genug gewartet, denn ich bin einer der wenigen, die noch mit ISDN überleben können, und da das Label erst nach dem DL refresht wird, hat es zu lang gedauert :)

Wunderbar!

Nun noch ne Frage, wenn ich das Programm jetzt beenden will (über form1), während der Thread noch arbeitet, muss ich da was besonderes beachten? Den Thread erst irgendwie beed nen oder so?

MfG Lefko :coder:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:56 Uhr.
Seite 1 von 2  1 2      

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