![]() |
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: |
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. |
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:
ich weiss nich, wieso das nich geht, deswegen bin ich auch eure hilfe angewiesen!
//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; MfG Lefko :wall: |
Re: Die erste Thread-Programmierung...
du must das form1 noch in die uses schreiben der threadunit
|
Re: Die erste Thread-Programmierung...
Zitat:
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 |
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 :) |
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:
Habe dabei keine Syntax-Fehler bekommen, das ausführen des Threads klappt auch.
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. [edit] Sorry, waren ein paar Flüchtigkeitsfehler drin. [/edit] |
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. |
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:
und das die Caption des Label nur in der Prozedur
Synchronize(UpdateForm1);
Delphi-Quellcode:
geändert werden kann.
TDownloadThread.UpdateForm1;
|
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. |
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