My PC is connected to two electronic devices that send data using a TCP connection. I would like to develop a Delphi program able to log all this data. In the following code I create two TCPClients using two threads. I am able to log data from one device using one thread, but when two threads are runnning the application freezes. I don´t have experience programming in Delphi, sorry if there are too many mistakes... I am using Delphi 7. What can I do to avoid freezing the app?
Thanks in advance
//************************************************************************//
type TThreadConn1 = class(TThread)
private
protected
procedure Execute; override;
end;
type TThreadConn2 = class(TThread)
private
protected
procedure Execute; override;
end;
var
Form1: TForm1;
TCP1: TThreadConn1;
TCP2: TThreadConn2;
flag1: bool;
flag2: bool;
implementation
{$R *.dfm}
//******************************Connection 1******************************//
procedure TThreadConn1.Execute; //Connect+loop read buffer+disconnect
begin
Form1.IdTCPClient1.Connect;
While flag1 = false do
Form1.IdTCPClient1.CurrentReadBuffer;
Form1.IdTCPClient1.Disconnect;
end;
procedure TForm1.ButtonConnection1Click(Sender: TObject);
begin
flag1:=false;
TCP1 := TThreadConn1.Create(false); //Launch thread
end;
procedure TForm1.ButtonDisconnection1Click(Sender: TObject);
begin
flag1:=true;
if (TCP1.Terminated = false) then
TCP1.Terminate; //Is it ok to finish this way a thread?
end;
//******************************Connection2******************************//
procedure TThreadConn2.Execute; //Connect+loop read buffer+disconnect
begin
Form1.IdTCPClient2.Connect;
While flag2 = false do
Form1.IdTCPClient1.CurrentReadBuffer;
Form1.IdTCPClient2.Disconnect;
end; { of procedure }
procedure TForm1.ButtonConnection2Click(Sender: TObject);
begin
flag2:=false;
TCP2 := TThreadConn2.Create(false);
end;
procedure TForm1.ButtonDisconnection2Click(Sender: TObject);
begin
flag2:=true;
if (TCP2.Terminated = false) then
TCP2.Terminate;
end;
end.
You don't need to create two separate threads that do the same thing. Create one class and then instantiate multiple copies of it. Try this instead:
type
TThreadConn = class(TThread)
private
FClient: TIdTCPClient;
protected
procedure Execute; override;
public
constructor Create(AClient: TIdTCPClient);
end;
var
TCP1: TThreadConn = nil;
TCP2: TThreadConn = nil;
constructor TThreadConn.Create(AClient: TIdTCPClient);
begin
inherited Create(False);
FClient := AClient;
end;
procedure TThreadConn.Execute;
begin
FClient.Connect;
try
while Terminated = false do
FClient.CurrentReadBuffer;
finally
FClient.Disconnect;
end;
end;
procedure TForm1.ButtonConnection1Click(Sender: TObject);
begin
TCP1 := TThreadConn.Create(TIdTCPClient1);
end;
procedure TForm1.ButtonDisconnection1Click(Sender: TObject);
begin if (TCP1 <> nil) then begin TCP1.Terminate; TCP1.WaitFor; FreeAndNil(TCP1); end; end;
procedure TForm1.ButtonConnection2Click(Sender: TObject);
begin TCP2 := TThreadConn.Create(IdTCPClient2); end;
procedure TForm1.ButtonDisconnection2Click(Sender: TObject);
begin
if (TCP2 <> nil) then
begin
TCP2.Terminate;
TCP2.WaitFor;
FreeAndNil(TCP2);
end;
end;