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