Является ли TIdTCPServer. OnConnect.OnConnect вызывается из основного потока?

#delphi #indy #tcpserver #delphi-10.3-rio

#delphi #indy #tcpserver #delphi-10.3-rio

Вопрос:

Я не знаю, можно ли получить доступ к данным из основного потока в событии TIdTCPServer.OnConnect или OnDisconnect . Вызывается ли этот метод из основного потока или другого потока? Я хочу зарегистрировать IP в TMemo и включить или отключить некоторые кнопки.

Комментарии:

1. Знаете ли вы, что вы можете легко протестировать это самостоятельно с помощью отладчика? Установите точку останова в таком обработчике событий и считайте идентификатор потока / имя из отладчика.

2. i.postimg.cc/VLMxV2tp/screenshot-5.png что это значит ?

3. @MarusNebunu это означает, что ваш OnConnect обработчик событий вызывается TIdContext объектом, который выполняется в рабочем потоке, который представлен TIdThread классом Indy

Ответ №1:

TIdTCPServer является многопоточным компонентом. Все его OnConnect , OnDisconnect , OnExecute и OnException события запускаются в контексте рабочего потока, который представлен TIdContext объектом события. Этот поток управляет TCP-соединением клиента в TIdContext.Connection свойстве.

OnListenException Событие запускается в контексте другого рабочего потока, который прослушивает клиентские подключения и создает TIdContext потоки.

Итак, TIdTCPServer обработчики событий должны синхронизироваться с основным потоком при доступе к элементам управления пользовательского интерфейса и другим общим данным.

Ответ №2:

Я полагаю, что он вызывается в своем собственном контексте потока.. Лучше защитить с помощью Synchronize() или Queue()… Пример:

 procedure TMainForm.IdTCPSyncServerConnect(AContext: TIdContext);
var
  AClientIP: string;
begin
 
  AClientIP := AContext.Binding.PeerIP;
  TThread.Synchronize(nil,
    procedure
    var lItem : TListItem;
    begin
      Inc(FClientCount);
      lblClientConnections.Caption := IntToStr(FClientCount);
      lItem := lstClients.Items.Add;
      lItem.Caption := AClientIP;
      lItem.SubItems.Add(AClientIP);
      lItem.SubItems.Add(DateTimeToStr(Now));
    end
  );
end;
  

Комментарии:

1. В таком примере я бы использовал TThread.Queue() вместо этого, чтобы избежать блокировки клиентского потока, чтобы он не зависел от пользовательского интерфейса. И я бы также сохранил либо TIdContext в TListItem.Data свойстве, либо TListItem в TIdContext.Data свойстве, чтобы OnDisconnect событие могло найти подходящее TListItem для удаления его из TListView .