Hallo,
das Thema hat mir keine Ruhe gelassen, da ich selber dieses Problem in eigenen Projekten habe bzw. hatte.
Eine
Exception trat in meinen Programmen aber nur auf, wenn ich es aus der
IDE mit dem Debugger gestartet habe.
Als kleines Beispiel habe ich Deine Thread-Klasse etwas umgebaut. Die Events TForm1.ClientConnected und TForm1.ClientDisconnected
habe ich ganz rausgenommen. Der Schreibvorgang Client.IOHandler.WriteLn(tcpStringSend); liegt jetzt im Hauptthread von Form1.
Vielleicht hilft das ein bischen.
Delphi-Quellcode:
interface
const
WM_CLIENTANSWER = WM_USER+1;
//*** TReadingThread
type
TReadingThread=
class(TThread)
private
FOutStr:
string;
FClient: TIdTCPClient;
procedure HandleInput;
protected
procedure Execute;
override;
public
constructor Create(ATCPClient: TIdTCPClient);
end;
//*** TForm1
type
TForm1 =
class(TForm)
//...
private
{ Private-Deklarationen }
procedure AnswerEvent(
var Msg: TMessage);
Message WM_CLIENTANSWER;
//...
end;
//...
implementation
constructor TReadingThread.Create(AClient: TIdTCPClient);
begin
TLog.AddMsg('
DEBUG: TReadingThread.Create');
FClient := AClient;
inherited Create(False);
end;
procedure TReadingThread.HandleInput;
var
cmd:
string;
begin
if FClient.Connected
then
begin
try
cmd:=FClient.IOHandler.ReadLn(#3);
TLog.AddMsg('
DEBUG: TReadingThread.Execute. Cmd: ' + cmd);
except
on E:
Exception do
begin
cmd:=E.
Message;
TLog.AddMsg('
DEBUG: TReadingThread.Execute. Err: ' + cmd);
end;
end;
PostMessage(Form1.Handle,WM_CLIENTANSWER,integer(@cmd),0);
end else Terminate;
end;
procedure TReadingThread.Execute;
begin
while not Terminated
do
begin
HandleInput;
end;
end;
procedure TForm1.AnswerEvent(
var Msg: TMessage);
//Antwort vom Thread übernehmen
var
CmdStr, tcpStringSend:
String;
P: ^
string;
begin
P:=Pointer(Msg.WParam);
CmdStr:=P^;
TelegramNr := copy(CmdStr, 1, 2);
tcpStringSend := #2 + TelegramNr + '
001050QU' + #3;
if Client.Connected
then Client.IOHandler.WriteLn(tcpStringSend);
//Nur schreiben, wenn Verbindung noch besteht!
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Host:
string;
Port: Integer;
begin
Host := '
192.168.100.74';
Port := StrToInt('
4100');
Client.Host := Host;
Client.Port := Port;
try
Client.Connect;
except
on E:
Exception do
TLog.AddMsg('
Error: ' + E.
Message);
end;
if Client.Connected
then rt:=TReadingThread.Create(Client);
end;
procedure TForm1.Button2Click(Sender: TObject);
//Disconnect reicht; der Thread terminiert sich selbst!
begin
Client.IOHandler.InputBuffer.Clear;
try
Client.Disconnect;
except
on E:
Exception do
TLog.AddMsg('
Error: ' + E.
Message);
end;
end;