【问题标题】:Is TIdTCPServer.OnConnect called from the main thread?TIdTCPServer.OnConnect 是从主线程调用的吗?
【发布时间】:2020-12-26 18:14:49
【问题描述】:

我不知道在TIdTCPServer.OnConnectOnDisconnect事件中从主线程访问数据是否可以。这个方法是从主线程还是其他线程调用的?我想在TMemo 中记录IP,并启用或禁用一些按钮。

【问题讨论】:

  • 您知道您可以使用调试器轻松地自行测试吗?在此类事件处理程序中设置断点并从调试器中读取线程 ID/名称。
  • @MarusNebunu 这意味着您的 OnConnect 事件处理程序正在被 TIdContext 对象调用,该对象在由 Indy 的 TIdThread 类表示的工作线程中运行

标签: delphi indy tcpserver delphi-10.3-rio


【解决方案1】:

TIdTCPServer 是一个多线程组件。它的OnConnectOnDisconnectOnExecuteOnException 事件都在由事件的TIdContext 对象表示的工作线程的上下文中触发。该线程在 TIdContext.Connection 属性中管理客户端 TCP 连接。

OnListenException 事件在不同工作线程的上下文中触发,该工作线程侦听客户端连接并创建 TIdContext 线程。

所以是的,TIdTCPServer 事件处理程序在访问 UI 控件和其他共享数据时必须与主线程同步。

【讨论】:

    【解决方案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;
    

    【讨论】:

    • 在这种示例中,我将使用TThread.Queue() 来代替,以避免阻塞客户端线程,因此它不依赖于 UI。我还将TIdContext 存储在TListItem.Data 属性中,或者将TListItem 存储在TIdContext.Data 属性中,以便OnDisconnect 事件可以找到适当的TListItem 以将其从@987654329 中删除@.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    相关资源
    最近更新 更多