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:
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;
Die Hauptgedanken dabei:
- Der Thread bekommt die Referenzen auf die zu verwendenen Objekte übergeben und verwendet sie dort (besser noch: die Connection (FClient ist nur ihm bekannt)
- Das Aktualisieren des GUIs findet im Haupthread statt (unter Verwendung von Synchronize)
Erzeugt werden könnte Dein Thread innerhalb des Formulars dann wie folgt:
Self.FThread:= TMyThreadClass.Create(Self.Client1, Self.Memo1);