EmirZ
EmirZ

Reputation: 646

Why does Indy 10's echo server have high CPU usage when the client disconnects?

When I disconnect echo client like :

EchoClient1.Disconnect;

client disconnects fine... but EchoServer does NOT EVEN register client disconnection and it ends up with high process usage !?!?

in every example and every doc it says that calling EchoClient.Disconnect is sufficient !

anyone, any idea ?

(I am working in Win7, could that be a problem ?)

Server code :

procedure TForm2.EServerConnect(AContext: TIdContext);
begin
  SrvMsg.Lines.Add('ECHO Client connected !');
end;

procedure TForm2.EServerDisconnect(AContext: TIdContext);
begin
 SrvMsg.Lines.Add('ECHO Client disconnected !');
end;

problem is "TForm2.EServerDisconnect" never executes !?!?

Upvotes: 1

Views: 1204

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 597941

The code shown is NOT THREAD SAFE. Any Indy event that provides access to a TIdContext object is fired in the context of a worker thread that runs that object. Access to UI components must be done in the context of the main thread instead. If you do not follow that rule, all kinds of unexpected bad things can happen. You need to synchronize with the main thread, eg:

uses
  ..., IdSync;

procedure TForm2.EServerConnect(AContext: TIdContext);
begin
  TIdNotify.NotifyMethod(ClientConnected);
end;

procedure TForm2.ClientConnected;
begin
  SrvMsg.Lines.Add('ECHO Client connected !');
end;

procedure TForm2.EServerDisconnect(AContext: TIdContext);
begin
  TIdNotify.NotifyMethod(ClientDisconnected);
end;

procedure TForm2.ClientDisconnected;
begin
  SrvMsg.Lines.Add('ECHO Client disconnected !');
end;

Upvotes: 2

Rob Kennedy
Rob Kennedy

Reputation: 163357

Find out for yourself by using the debugger.

If your program has high CPU usage, assume it's stuck in a loop. The debugger can help you figure out which loop, and why. While the server is running in the debugger and exhibiting the problem, press the "pause" button. The debugger will interrupt your program and show you the line your program was executing. Use the call stack to show you how your program got to that line. Find the loop that you suspect is the culprit. Resume and pause your program a few more times to see whether you always stop somewhere in that same loop. Now analyze the code to figure out why the loop doesn't terminate.

You might have to activate a different thread; the main GUI thread will probably be waiting in a call to GetMessage, which is normal.

Make sure you're using the latest version of Indy. Don't use the version that came with your copy of Delphi.

Upvotes: 3

Related Questions