转的:
With that said, this kind of code would be better implemented using a worker thread instead of a timer.
1 - Create a new class derived from TThread (File > New > Other > Thread Object)
type
TDataEvent = procedure(const Data: string) of object;
TReadingThread = class(TThread)
private
FClient: TIdTCPClient;
FData: string;
FOnData: TDataEvent;
procedure DataReceived;
protected
procedure Execute; override;
public
constructor Create(AClient: TIdTCPClient); reintroduce;
property OnData: TDataEvent read FOnData write FOnData;
end;
constructor TReadingThread.Create(AClient: TIdTCPClient);
begin
inherited Create(True);
FClient := AClient;
end;
procedure TReadingThread.Execute;
begin
while not Terminated do
begin
FData := IdTCPClient1.IOHandler.ReadLn;
if (FData <> '') and Assigned(FOnData) then
Synchronize(DataReceived);
end;
end;
procedure TReadingThread.DataReceived;
begin
if Assigned(FOnData) then
FOnData(FData);
end;
2 - Modify your connection code:
IdTCPClient1.Connect;
try
Thread := TReadingThread.Create(IdTCPClient1);
Thread.OnData := DataReceived;
Thread.Resume;
except
IdTCPClient1.Disconnect;
raise;
end;
...
if Assigned(Thread) then Thread.Terminate;
try
IdTCPClient1.Disconnect;
finally
if Assigned(Thread) then
begin
Thread.WaitFor;
FreeAndNil(Thread);
end;
end;
...
procedure TForm1.DataReceived(const Data: string);
begin
ShowMessage(Data);
end;