Почему эхо-сервер Indy 10 имеет высокую загрузку процессора, когда клиент отключается? - PullRequest
1 голос
/ 29 декабря 2010

Когда я отключаю эхо-клиент, как:

EchoClient1.Disconnect;

клиент отключается нормально ... но EchoServer НЕ ДАЖЕ регистрирует отключение клиента, и это приводит к высокой загрузке процесса!* в каждом примере и в каждом документе говорится, что достаточно вызвать EchoClient.Disconnect!

кто-нибудь, есть идеи?

(я работаю в Win7, это может быть проблемой?)

Код сервера:

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;

Проблема в том, что «TForm2.EServerDisconnect» никогда не выполняется!?!?

Ответы [ 2 ]

3 голосов
/ 29 декабря 2010

Узнайте сами с помощью отладчика.

Если ваша программа имеет высокую загрузку процессора, предположим, что она застряла в цикле. Отладчик может помочь вам выяснить, какой цикл и почему. Пока сервер работает в отладчике и выявляет проблему, нажмите кнопку «Пауза». Отладчик прервет вашу программу и покажет вам строку, которую выполняла ваша программа. Используйте стек вызовов , чтобы показать вам, как ваша программа попала на эту линию. Найдите петлю, которую вы подозреваете, является виновником. Возобновите и приостановите вашу программу еще несколько раз, чтобы увидеть, всегда ли вы останавливаетесь где-то в этом цикле. Теперь проанализируйте код, чтобы выяснить, почему цикл не завершается.

Возможно, вам придется активировать другую ветку; основной поток графического интерфейса, вероятно, будет ожидать вызова GetMessage, что является нормальным.

Убедитесь, что вы используете последнюю версию Indy . Не используйте версию, поставляемую с вашей копией Delphi.

2 голосов
/ 01 января 2011

Показанный код НЕ БЕЗОПАСНЫЙ. Любое событие Indy, предоставляющее доступ к объекту TIdContext, запускается в контексте рабочего потока, который запускает этот объект. Вместо этого доступ к компонентам пользовательского интерфейса должен осуществляться в контексте основного потока. Если вы не будете следовать этому правилу, могут произойти любые неожиданные неприятности. Вам необходимо синхронизироваться с основным потоком, например:

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;
...