繁体   English   中英

客户端连接到TIdTCPServer时线程数增加

[英]Thread count increasing when clients connect to TIdTCPServer

我有一个使用Delphi 10.1创建的64位服务器应用程序,在此应用程序中,我有一个TIdTCPServer组件。

当客户端连接时,线程数增加,而当客户端断开连接时,线程数没有减少。 Windows Server计算机上会发生此问题。 我不处理OnConnectOnDisconnect事件中的任何代码。 下面是我的OnExecute方法:

  try
      if not AContext.Connection.IOHandler.InputBufferIsEmpty then
      begin
        AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes) ;
        ReceivedIDBytes.ClientSocket := AContext.Connection;
        MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
        IndySleep(50);
      end;
      IndySleep(5);
  except
  end;

我应该使用Application.ProcessMessages()解决此问题吗?

由于线程数增加,我需要定期重新启动Server应用程序。

不要吞下异常! Indy使用异常来报告诸如套接字断开连接/错误之类的事件( EIdConnClosedGracefullyEIdSocketError等)。 TIdTCPServer内部处理其事件处理程序引发的未捕获异常,以了解何时清除管理接受套接字的线程。 通过吞下异常,可以防止TIdTCPServer正确进行清理。

如果出于某种原因(清理,日志记录等1 )需要捕获异常,则至少应重新引发从EIdException派生的任何异常。 TIdTCPServer处理Indy生成的异常,尤其是由于套接字断开而发生的异常。

1: TIdTCPServer.OnException考虑使用TIdTCPServer.OnException事件。

try
  if not AContext.Connection.IOHandler.InputBufferIsEmpty then
  begin
    AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes);
    ReceivedIDBytes.ClientSocket := AContext.Connection;
    MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
    IndySleep(50);
  end;
  IndySleep(5);
except
  on E: Exception do
  begin
    ...
    if E is EIdException then
      raise; // <-- add this!
  end;
end;

我还建议您也摆脱IndySleep()调用。 您实际上并不需要它们,让Indy在等待新数据到达时为您做睡眠:

try
  if AContext.Connection.IOHandler.InputBufferIsEmpty then
  begin
    // the next call sleeps until data arrives or the specified timeout elapses...
    AContext.Connection.IOHandler.CheckForDataOnSource(55);
    AContext.Connection.IOHandler.CheckForDisconnect;
    if AContext.Connection.IOHandler.InputBufferIsEmpty then Exit:
  end;
  AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes);
  ReceivedIDBytes.ClientSocket := AContext.Connection;
  MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
except
  on E: Exception do
  begin
    ...
    if E is EIdException then
      raise;
  end;
end;

或者,使用TIdIOHandler.ReadBytes()代替直接使用TIdBuffer.ExtractToBytes()

try
  SetLength(ReceivedIDBytes.PointerMessage.tyTIDBytes, 0);
  // the next call sleeps until data arrives or the IOHandler.ReadTimeout elapses...
  AContext.Connection.IOHandler.ReadBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes, -1, False);
  if Length(ReceivedIDBytes.PointerMessage.tyTIDBytes) > 0 then
  begin
    ReceivedIDBytes.ClientSocket := AContext.Connection;
    MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
  end;
except
  on E: Exception do
  begin
    ...
    if E is EIdException then
      raise;
  end;
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM