tes*_*345 1 delphi indy tcpserver indy10 delphi-10.1-berlin
我有一个使用Delphi 10.1创建的64位服务器应用程序,在此应用程序中我有一个TIdTCPServer组件。
当客户端连接时,线程数增加,而当客户端断开连接时,线程数没有减少。Windows Server计算机上会发生此问题。我没有处理OnConnect和OnDisconnect事件中的任何代码。下面是我的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;
Run Code Online (Sandbox Code Playgroud)
我应该使用它Application.ProcessMessages()来解决此问题吗?
由于线程数增加,我需要定期重新启动Server应用程序。
不要吞下异常!印地使用了异常报告之类的东西插座断开/错误(EIdConnClosedGracefully,EIdSocketError,等)。 TIdTCPServer在内部处理由其事件处理程序引发的未捕获异常,以了解何时清理管理接受的套接字的线程。通过吞下异常,您将无法TIdTCPServer正确进行清理。
如果出于某种原因(清除,日志记录等1)需要捕获异常,则EIdException至少应重新引发从派生的异常。让我们TIdTCPServer处理Indy生成的异常,尤其是由于套接字断开而发生的异常。
1:考虑使用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;
Run Code Online (Sandbox Code Playgroud)
我也建议您摆脱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;
Run Code Online (Sandbox Code Playgroud)
或者,使用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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |