![]() |
Thread Anfängerfrage
Hallo,
ich habe amgefangen einen Netzwerkchat zu programmieren, und bin zu der Erkenntnis gekommen, dass ich threads brauche. Da ich mich mit threads nicht auskenne, funktioniert folgender Code nicht;
Delphi-Quellcode:
Also,
unit thread;
interface uses Classes; type mythread = class(TThread) private { Private-Deklarationen } protected procedure Execute; override; constructor create; public procedure lesen; // lesen soll später nachrichten aus einer tcp connection lesen end; implementation { Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen nur in einer Methode namens Synchronize aufgerufen werden, z.B. Synchronize(UpdateCaption); und UpdateCaption könnte folgendermaßen aussehen: procedure mythread.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; } { mythread } constructor mythread.create; begin inherited create(false); end; procedure mythread.lesen; var test:string; begin test := client.readln; //client ist ein tcpclient auf der form, wo ich den thread verwenden will memo1.lines.add(test); //memo1 ist ein memo auf der form wo ich den thread verwenden will end; procedure mythread.Execute; begin { Thread-Code hier einfügen } lesen; end; end. der client ist nicht bekannt, wie muss ich das machen gleiches gilt für memo1 Gruß Spurius |
Re: Thread Anfängerfrage
Nimm die Unit der Form in die Thread Unit auf. :roll:
|
Re: Thread Anfängerfrage
hab ich gemacht, aber dann kommt
[Fataler Fehler] modul.pas(8): Überkreuzender Bezug zweier Units auf 'modul' und in der hilfe steht, das man da wenn möglich in der implementation machen soll(oder so), und dann gehts auch nicht. Gruß Spurius |
Re: Thread Anfängerfrage
ok, jetzt kommt die fehlermeldung nicht mehr :)
mal sehen, wie's weitergeht ... Gruß Spurius |
Re: Thread Anfängerfrage
Schon wieder ne Frage :roll:
Wie kann ich mythread jetzt in der hauptunit (name: modul) verwenden? muss ich da auch den constructor aufrufen? kann mir vielleicht jemand den code posten, wie ich mythread da einbaue? Gruß Spurius |
Re: Thread Anfängerfrage
Hallo Spurius,
Du hast zunächst das Problem, dass Dein Thread-Objekt (unabhängig davon, dass es sich um einen Thread handelt) keine Kenntnis von client hat, stattdessen wird dies wahrscheinlich eine Exemplarvariable von Deiner Form-Klasse sein. Auch wenn Du nun die Unit des Forms einbinden solltes, wüsstest Du zwar von der Formular-Klasse, aber nicht, welches Formular-Exemplar (schließlich könnten mehrere Formulare der selben Klasse erzeugt werden) nun tatsächlich verwendet werden soll. Darüber hinaus hast Du einen entscheidenen Kommentar mit in Deiner Unit: "Niemals VCL-Controls aus einem Thread heraus verwenden". Deine Änderung des Memos verstößt gegen diese Forderung... Eine Mögliche Lösung soll diese Pseudocode verdeutlichen
Delphi-Quellcode:
Die Hauptgedanken dabei:
type
TMyThreadClass = class(TThread) private FClient : TSomeClient; FMemo : TSomeVCLControl; procedure UpdateMemo; protected procedure Execute;override; public constructor Create(const AClient: TSomeClient; const AMemo: TSomeVCLControl); end; constructor TMyThreadClass.Create(const AClient: TSomeClient; const AMemo: TSomeVCLControl); begin inherited Create(True); Assert(Assigned(AClient)); Assert(Assigned(AMemo)); //copy references to member vars FClient:= AClient; FMemo:= AMemo; //start thread Resume; end; procedure TMyThreadClass.Execute; begin while not Terminated do if FClient.HasData then //update vcl controls only within the mainthread! Synchronize(UpdateMemo); else //better: use some syncobj connected with // FClient to wait for! Sleep(100); end; procedure TMyThreadClass.UpdateMemo; begin //will be executed within the mainthread FMemo.Lines.Append(FClient.ReadLn); end;
Erzeugt werden könnte Dein Thread innerhalb des Formulars dann wie folgt:
Delphi-Quellcode:
Self.FThread:= TMyThreadClass.Create(Self.Client1, Self.Memo1);
|
Re: Thread Anfängerfrage
Hallo,
ich hab zu demo Code ein paar Fragen: 1. FClient : TSomeClient; tsomeclient, tsomevclcontrol sind feste Ausdrücke, nicht nur Bsp. ? FMemo : TSomeVCLControl; 2. public constructor Create(const AClient: TSomeClient; heisst dass, das irgendéin client, bzw. memo const AMemo: TSomeVCLControl); erzeugt wird, dem ich dann später einen vorhandenen client zuweisen kann? 3. constructor TMyThreadClass.Create(const AClient: TSomeClient; const AMemo: TSomeVCLControl); begin inherited Create(True); wenn ich hier create(false) eingebe, dann brauch ich später kein resume? Assert(Assigned(AClient)); was machen die 2 zeilen? Assert(Assigned(AMemo)); //copy references to member vars FClient:= AClient; wird hier dem beliebigen client der vorhandene zugewiesen? FMemo:= AMemo; //start thread Resume; end; 4. procedure TMyThreadClass.Execute; den abschnitt versteh ich nicht begin while not Terminated do if FClient.HasData then //update vcl controls only within the mainthread! Synchronize(UpdateMemo); else //better: use some syncobj connected with // FClient to wait for! Sleep(100); end; So, ich will hier nicht nerven, aber ich denke, es ist besser was zu verstehen als nur den Code abzutippen. Gruß Spurius |
Re: Thread Anfängerfrage
Hi,
suche doch mal nach TTimerThread im Forum, ich galaube ich habe da auch ein Beispiel geschrieben. Zur Info: Eine IP Verbindung immer aus dem Haupthread "ThreadSync" mit
Delphi-Quellcode:
aufbauen.Synchronize( DoConnect ); Ich bin gestern "mal wieder drüber" gestolpert. Ich habe TTimerThread in alten code eingebaut um eine IP Verbindung aus dem Thread heraus aufzubauen (ohne Synchronize ) und den Status zu überwachen, Reconnect ect. Ich habe dann in die TTimerThread class noch
Delphi-Quellcode:
Bitte Info wenn du die neue haben möchtest.
TSyncMethod = (smThreadSync, smNone);
... FSyncMethod: TSyncMethod; ... ... if FSyncMethod = smNone then Notify else Synchronize( Notify ); mfg Rumpi |
Re: Thread Anfängerfrage
Hui, das wird wohl 'ne lange Antwort :gruebel:...
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Ich hoffe, dass ich Dir mit diesen Ausführungen etwas weiter helfen konnte. |
Re: Thread Anfängerfrage
Hallo,
ich hab leider immer noch nicht alles verstanden. Was kann ich denn konkret einsetzten:
Delphi-Quellcode:
für tsomeclient, tsome vclcontrol?
FClient : TSomeClient;
FMemo : TSomeVCLControl; Gruß Spurius |
Re: Thread Anfängerfrage
Hallo Spurius,
das hängt davon ab, was Du verwendest. Ich denke, dass Du mit TMemo und zB TidTCPClient oä arbeitest? Im zweifelsfall kann Du ads im OI nachsehen, sofern sich die Komponenten in einer Form befinden. Bitte lies auch in der Hilfe zu der Klient-Komponete, die Du verwendest, ob sie Threadsicher (nicht nur -fähig!) ist, andernfalls müsstest Du die Aufrufe dieser Komponete ebenfalls synchronisieren... Alles halb so wild ;) |
Re: Thread Anfängerfrage
Hallo,
ja ich verwende tidtcpclient, aber wenn ich im thread client: tidtcpclient; schreibe, kommt die meldung, dass das unbekannt sei Gruß Spurius |
Re: Thread Anfängerfrage
Sinngemäß aus der OH: Du kannst nur Typen verwenden, die zuvor deklariert wurden.
In Deinem Fall ist die Klasse TidTCPClient in einer Indy-Unit deklariert, die Du einbinden musst. Bei der Arbeit mit Formularen geschieht dies beim Platzieren einer Komponente auf einer Form oder einem Datenmodul automatisch. Wirf mal einen Blick in den uses-Abschnitt der Unit Deiner Formular-Klasse. |
Re: Thread Anfängerfrage
Hi,
der Vorschlag von Choose wird zwar funktionieren, aber er ist meiner Meinung nicht so gut. Ich würde es so machen: Nur für den Zugriff auf TMemo und ähnliche Komponenten Synchronize verwenden, da dieser Code im Mainthread ausgeführt wird. (nur das notwendigste mit synchronize ausführen) Dein TIdTCPClient sollte zum Thread gehören (d.h. im Thread erstellen, initalisieren und am Ende freigeben), damit er im Thread arbeiten kann und nicht im Mainthread arbeiten muss. Wenn du (fast) alles im Mainthread ausführst, dann kannst du dir den zweiten Thread gleich sparen... Ungefähr so würde ich es machen:
Delphi-Quellcode:
type
TMyThreadClass = class(TThread) private FClient : TSomeClient; FMemo : TSomeVCLControl; procedure UpdateMemo; protected s: string; procedure Execute;override; public constructor Create(Host: string; Port: integer; const AMemo: TSomeVCLControl); end; constructor TMyThreadClass.Create(Host: string; Port: integer; const AMemo: TSomeVCLControl); begin inherited Create(True); Assert(Assigned(AMemo)); FClient:= TIdTCPClient.Create(nil); FClient.Host:=Host; FClient.Port:=Port; //copy references to member vars FMemo:= AMemo; //start thread Resume; end; procedure TMyThreadClass.Execute; begin try FClient.Connect; while (not Terminated) and (FClient.Connected) do begin s:=FClient.Readln; Synchronize(UpdateMemo); end; finally FClient.Free; end; end; procedure TMyThreadClass.UpdateMemo; begin //will be executed within the mainthread FMemo.Lines.Append(s); end; |
Re: Thread Anfängerfrage
Hallo Kamil,
es ist sicherlich eleganter (Geheinmisprinzip, Zuständigkeitsprinzip), wenn alles, was die Connection betrifft, nur innerhalb des Threads abgehandelt wird. Das ist auch der Gedanke meiner Bemerkung in den Klammern gewesen: Zitat:
Delphi-Quellcode:
auch durch das Einbinden der Form-Unit nicht funktioniert...
client.ReadLn;
|
Re: Thread Anfängerfrage
@choose: muss zugeben, dass ich deinen Beitrag nur schnell überflogen und die Klammer deshalb übersehen habe. Hab mich mehr auf den Quellcode konzentriert. Da der Titel "Thread Anfängerfrage" lautet dachte ich, dass sowas erwähnt werden sollte. Deshalb wird auch der Unterschied zwischen threadsicher und threadfähig wahrscheinlich noch nicht ganz klar sein und die Anweisund "if FClient.HasData then" im Thread kann ganz schnell zu größeren Problemen führen, weil sie höchst wahrscheinlich auch synchronisiert werden sollte.
|
Re: Thread Anfängerfrage
So, ich meld mich mal wieder.
ich hab jetzt die threadunit fertig, und habe sie unter uses eingebunden, wo auch windows, sysutils etc. stehen. Mit
Code:
kann ich aber keinen Thread erzeugen. da kommt dann unbekannt tmythread.
Self.FThread:= TMyThread.Create(Self.Client1, Self.Memo1);
und wenn ich unter var, wo auch form : tform1 deklariert wird, fthread: tmythread deklarieren will kommt auch dass tmythread unbekannt sind. kann mir da jemand wieterhelfen? Thx Spurius |
Re: Thread Anfängerfrage
Hallo Spurius,
löse das Problem so, wie Du dem unbekannten Typ TMemo und TidTCPClient innerhalb des Deklaration von TMyThread begegnet bist. |
Re: Thread Anfängerfrage
da hab ich idtcpclient unter uses deklariert. mein thread heisst mythread, und die unit thread. soll ich da thread + mythread deklarieren oder wie?
ich blick da nicht so ganz durch, wär nett, wenn du mir weiterhelfen würdest. Gruß Spurius |
Re: Thread Anfängerfrage
Such mal in der OH. Dort habe ich zB das gefunden
Zitat:
|
Re: Thread Anfängerfrage
Hallo,
ich hab das Buch nicht, kannst du mir nicht einfach sagen, wie das geht? Thx Spurius |
Re: Thread Anfängerfrage
Hallo Spurius,
bitte verstehe mich nicht falsch: Ich helfe wirklich gerne. Das Problem ist bei den gegenseitig verwendeten Units aber weniger das Wie für Deine konkrete Problemstellung als das Warum muss man bei der Verwendung von Typen, die in anderen Units deklariert sind, auf diese oder eine andere Weise reagieren. Dies bedarf einer umfassenderen Erklärung statt einem kurzen Statement, mithilfe von drei Zeilen Code, die zudem, wenn an falscher Stelle platziert, unweigerlich vermeidbare Folgefragen nach sich ziehen würden. Es handelt sich beim Einbinden von Units unter Pascal wie Delphi um ein grundlegendes Prinzip, das verstanden werden will und dessen Kenntnis von jeder Bilbiothek von Dritten (zB Komponenten-Suites) vorrausgesetzt wird. Ich halte es deshalb für sinnvoll, das dahinter stehende Prinzip zu erläutern. Diese Thematik ist allerdings in der OH besser und umfassender beschrieben, als ich es hier könnte und sie bietet sich Dir als Informationsquelle an, die Du kurzfristig und zu jeder Zeit befragen kannst. Wenn Du also Dein Begleitmaterial zu Delphi verlegt hast, solltest Du sie stattdessen mit den Stichworten "unit-Klauseln" befragen. Dort findest Du auch Informationen zu dem von Dir entdeckten Prinzip der "zirkulären Unit-Referenzen" sowie dem Thema, dass Du zur Lösung Deines akuten Problem zu benötigen scheinst: "Mehrere und indirekte Unit-Referenzen", dem Abschnitt aus dem ich im letzten Posting zitiert habe und eigentlich schon die Lösung beschreibt. |
Re: Thread Anfängerfrage
Hallo,
also erstmal Danke, dass du mir soviel hilfst. Ich hab mir die uses-klauseln in der Hilfe angeschaut,(ich hab schülerversion, da war kein Handbuch dabei), bin aber nicht schlau daraus geworden, was das für mein Programm bedeutet. Ich habe bisher die Unit, in der der Thread geschrieben ist, unter den uses von meinem Hauptprogramm eingebunden. Aber wie kann ich den darin beschriebenen Thread jetzt einsetzten? Ich versteh das nicht :( Kannst du mir da vielleicht nochmal so ein Musterbeispiel machen, wie du es schonmal gemacht hast? Gruß Spurius |
Re: Thread Anfängerfrage
Hallo Spurius,
wenn ich Deine Antwort richtig interpretiere, ist die Fehlermeldung "Undefinierter Bezeichner" inzwischen verschwunden und Du weißt nichts ganz, wie Du ein Exemplar Deiner Klasse erzeugen kannst. Für ein ähnliches Szenario ist in der D7-OH unter TStringList dann "Verwendung von TStringList" und von dort "Eine neue Stringliste erstellen" beschrieben. Der Text handelt von einem zum Zeitpunkt der Formularerstellung erzeugten Objekt einer Klasse, die man aus dem OI nicht direkt kennt, zeigt die Benutzung zu einem späteren Zeitpunkt und auch, wie man das Objekt wieder freigibt. Achtung: Treads-Objekte sollten vor der Freigabe unbedingt terminiert sein! Falls Du bei diesem Problem angelangt sein solltest, stelle die Frage am besten in einem neuen DP-Tread. |
Re: Thread Anfängerfrage
Hallo,
ich hab mit das mit tstringlist angeschaut, und probiert das nachzumachen. aber es ist ja nicht die thread-unit unbekannt, sondern mythread! hier mal mein code
Delphi-Quellcode:
das ist der anfang. vielleicht kann ich damit mein problem verdeutlichen.
unit modul;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls, ExtCtrls, Mask, ComCtrls, IdTCPServer,threadtest; // <- threadunit type TForm1 = class(TForm) Label1: TLabel; PageControl1: TPageControl; TabSheet1: TTabSheet; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Memo1: TMemo; connect: TButton; Button2: TButton; Edit1: TEdit; ip: TEdit; Port: TEdit; Edit2: TEdit; Button1: TButton; client: TIdTCPClient; Timer1: TTimer; server: TIdTCPServer; TabSheet2: TTabSheet; Label7: TLabel; Label8: TLabel; Label9: TLabel; Memo2: TMemo; serverport: TEdit; servername: TEdit; Button4: TButton; Button5: TButton; Memo3: TMemo; Button3: TButton; procedure connectClick(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure serverConnect(AThread: TIdPeerThread); procedure serverExecute(AThread: TIdPeerThread); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public fthread: tmythread; //hier soll ein neuer thread erstelt werden, aber end; mythread ist unbekannt! var Form1: TForm1; implementation uses thread; {$R *.dfm} procedure TForm1.connectClick(Sender: TObject); begin client.Port := strtoint(port.Text); client.Host := ip.Text; client.Connect; end; procedure TForm1.Button2Click(Sender: TObject); begin client.Writeln(edit2.Text + ': ' + edit1.text); end; procedure TForm1.FormCreate(Sender: TObject); begin memo1.Lines[0] := 'Chatprotokoll'; memo2.lines[0] := 'Chatprotokoll'; memo3.Lines[0] := 'Angemeldete Chatter'; end; Gruß Spurius |
Re: Thread Anfängerfrage
Ist die Klasse tmythread im Interface-Teil der Unit threadtest deklariert?
[edit]Welchen Zweck hat die Unit thread, die Du in der Formular-Unit modul einbindest?[/edit] |
Re: Thread Anfängerfrage
Hallo,
also ich hatte einen thread mythread und nicht Tmythread erstellt. der thread geht jetzt :) aber er friert ein, ich denke das liegt daran, dass es client.hasdata nicht gibt.
Code:
Das ist meine Threadunit. und da der thread sonst immer ausgeführt wird, ist es ja klar, dass das prog einfriert. weisst du, was ich da hinter client einsetzten könnte?
unit threadtest;
interface uses Classes,idtcpclient,dialogs,StdCtrls,sysutils; type tmythread = class(TThread) private fclient:tidtcpclient; fmemo:tmemo; procedure updatememo; protected procedure Execute; override; public constructor create(const aclient: tidtcpclient; const amemo: tmemo); end; implementation uses modul; constructor tmythread.create(const aclient: tidtcpclient; const amemo: tmemo); begin inherited create(true); fclient := aclient; fmemo := amemo; resume; end; procedure tmythread.Execute; begin while not terminated do if fclient. then //<- hasdata ??? synchronize(updatememo) else sleep(100); end; procedure tmythread.updatememo; begin fmemo.Lines.Append(fclient.ReadLn); end; end. Gruß Spurius |
Re: Thread Anfängerfrage
Schau dir nochmal das was ich geschrieben habe an. Das sollte dir helfen.
|
Re: Thread Anfängerfrage
Jetzt hab ich aber mit viel Mühe den Thread hinbekommen, und würde den gern weiterverwenden.
Trotzdem Danke Spurius |
Re: Thread Anfängerfrage
Wenn du deinen Code nicht ändern wirst, dann wird dein Problem natürlich weiterhin bestehen... du muss schon was ändern und soviel ist das auch nicht.
|
Re: Thread Anfängerfrage
Ok, wenns nicht anders geht, soll ich einfach den code nehmen, den du schonmal gepostet hast?
und was ist da der Unterschied zu meinem? Ich mein, warum sollte das nicht einfrieren? Gruß Spurius |
Re: Thread Anfängerfrage
Spurius, der von mir gepostete Code war bewusst exemplarisch und kann nicht funktionieren, weil es die Eigenschaft HasData in der Klasse TidTCPClient nicht gibt!
Was Du als "einfrieren" beschreibst, sollte eigentlich ein Abbruch des Kompilerlaufs sein, der Dich auf diese Tatsache aufmerksam macht. In der OH findest Du eine Übersicht der zur Verfügung stehenden Eigenschaften und in einem Buch bestimmt auch Lösungen inkl. Beispiele für viele Grundsatzfragen zu Pascal/Delphi... |
Re: Thread Anfängerfrage
Der Unterschied liegt vorallem an UpdateMemo, das über Synchronize aufgerufen wird.
In dieser Funktion sollten keine blockierenden Aufrufe (wie z.B. TIdTCPClient.Readln, Sleep) stehen, da der Code nicht im Thread ausgeführt wird zu dem er gehört, sondern im Hauptthread deiner Anwendung, was natürlich deine Anwendung dann einfriert. Vielelicht hilft dir das ein wenig:
Code:
Schau dir mal dieses Tutorial an:
läuft im läuft im
Hauptthread MyThread | | |---->TMyThread.Create---->| | | | | | | | | | |<---Synchronize<--------| | | | | | | Ende von Sync. ------->| | | | | | | | | V V ![]() |
Re: Thread Anfängerfrage
Hallo,
könnt ihr mir nicht einfach sagen, wie ich das machen soll? Wo liegt denn mein Fehler? Im mainthread oder in mythread? Gruß Spurius |
Re: Thread Anfängerfrage
Wie sieht dein Code vom Thread gerade aus?
Wahrscheinlich ist der Fehler, dass der Code aus dem Thread im Hauptthread ausgeführt wird. Oder hast du es schon so gemacht wie ich es gepostet habe? |
Re: Thread Anfängerfrage
Hallo,
das ist meinThreadcode:
Delphi-Quellcode:
Was ist in deinem Code wesentlich anders? Oder was soll ich ändern?
unit threadtest;
interface uses Classes,idtcpclient,dialogs,StdCtrls,sysutils; type tmythread = class(TThread) private fclient:tidtcpclient; fmemo:tmemo; procedure updatememo; protected procedure Execute; override; public constructor create(const aclient: tidtcpclient; const amemo: tmemo); end; implementation uses modul; constructor tmythread.create(const aclient: tidtcpclient; const amemo: tmemo); begin inherited create(true); fclient := aclient; fmemo := amemo; resume; end; procedure tmythread.Execute; begin while not terminated do if fclient. then //<- hasdata ??? synchronize(updatememo) else sleep(100); end; procedure tmythread.updatememo; begin fmemo.Lines.Append(fclient.ReadLn); end; end. Gruß Spurius |
Re: Thread Anfängerfrage
Das Problem ist, wie Kamil bereits beschrieben hat, dass ReadLn geblockt ist, also die "Programmzeile so lange wartet bis tatsächlich ein String ankommt". Mit Syncronize wechselst Du in den Haupthread, so dass die Idee des Threads, nämlich diese Wartezeit unabhäng vom Hauptthread zu verbringen, untergraben wird...
Bei meiner exemplarischen Darstellung habe ich diesen Effekt durch eine fiktive Methode/Eigenschaft HasData kompensiert, die solange False zurückgibt, bis tatsächlich Daten vorhanden sind, so dass ReadLn niemals warten würde. Die Schleife
Delphi-Quellcode:
entspricht demnach im Wesentlichen einem Polling (tatsächlich nicht wirklich elegant).
while not Terminated do
if FClient.HasData then Synchronize(UpdateMemo) else Sleep(100); Um das Ganze in den Griff zu bekommen, solltest Du innerhalb von Execute eine Exemplar-Variable mit dem Ergebnis von ReadLn füllen und erst anschließend Synchronize aufrufen, also in etwa so
Delphi-Quellcode:
Beachte, dass Du innerhalb von UpdateMemo diese Exemplarvariable anstatt FClient verwendest!
while not Terminated do
begin FReceivedString:= FClient.ReadLn; Synchronize(UpdateMemo); end; Nachteil dieses Ansatzes ist die Tatsache, dass ReadLn per default "unendlich lange" wartet, Du also keine saubere Möglichkeit hast, den Thread zu beenden. Hier könnte ggf doch eine Variante des Pollings verwendet werden, damit zyklisch Terminated abgefragt wird... |
Re: Thread Anfängerfrage
Hallo,
ich hab nochmal deinen Code hier:
Delphi-Quellcode:
hier wird ja ein client created, was hat der mit meinem tatsächlichen client im mainthread zu tun?
Source:
type TMyThreadClass = class(TThread) private FClient : TSomeClient; FMemo : TSomeVCLControl; procedure UpdateMemo; protected s: string; procedure Execute;override; public constructor Create(Host: string; Port: integer; const AMemo: TSomeVCLControl); end; constructor TMyThreadClass.Create(Host: string; Port: integer; const AMemo: TSomeVCLControl); begin inherited Create(True); Assert(Assigned(AMemo)); FClient:= TIdTCPClient.Create(nil); FClient.Host:=Host; FClient.Port:=Port; //copy references to member vars FMemo:= AMemo; //start thread Resume; end; procedure TMyThreadClass.Execute; begin try FClient.Connect; while (not Terminated) and (FClient.Connected) do begin s:=FClient.Readln; Synchronize(UpdateMemo); end; finally FClient.Free; end; end; procedure TMyThreadClass.UpdateMemo; begin //will be executed within the mainthread FMemo.Lines.Append(s); end; und wenn ich den create, muss ich ja auch dafür port und host festlegen. aber die werden ja im mainthread über edits festgelegt. wie bekomm ich da werte? Gruß Spurius |
Re: Thread Anfängerfrage
Zitat:
Zitat:
Zitat:
|
Re: Thread Anfängerfrage
Zitat:
könntest Du kurz skizzieren, wie Du ohne Polling (sprich: ATimeOut<>IdTimeoutInfinite) den Thread sauber terminierst (if Self.Terminated) und trotzdem jedes Byte von FClient empfängst? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:57 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