简体   繁体   English

Indy TCP Server在停用时冻结

[英]Indy TCP Server freezing when deactivating

I have an Indy Server TIdTCPServer which has 3 bindings for different ports. 我有一个Indy Server TIdTCPServer ,它有3个不同端口的绑定。 If I connect a client to those 3 ports, and then deactivate the server, it gets stuck in what appears to be a deadlock. 如果我将客户端连接到这3个端口,然后停用服务器,它将陷入看似死锁的状态。 No matter what I do, it won't respond to my click, it won't even report "not responding" to Windows. 无论我做什么,它都不会响应我的点击,它甚至不会报告“没有响应”Windows。 If I disconnect the client(s) before deactivating the server, everything goes just perfect. 如果我在停用服务器之前断开客户端连接,一切都很完美。 I mean "deactivating" as in Server.Active:= False; 我的意思是“停用”,如Server.Active:= False; .

Has anyone else experienced this? 还有其他人经历过这个吗? What might be causing it? 可能是什么造成的? I have nothing happening in here which crosses over threads which could in turn cause a deadlock (for example GUI updates). 我在这里没有发生任何跨越线程的事情,这可能反过来导致死锁(例如GUI更新)。 I tried an Antifreeze component TIdAntiFreeze but no luck. 我试过Antifreeze组件TIdAntiFreeze但没有运气。

TIdTCPServer is a multi-threaded component. TIdTCPServer是一个多线程组件。 A deadlock during server deactivation means that one or more of its client threads is not terminating correctly. 服务器停用期间的死锁意味着其一个或多个客户端线程未正确终止。 That usually means that your server event handlers are doing something they should not be doing, typically either catching and discarding Indy's internal exceptions to itself, synchronizing with the thread context that is busy terminating the server, or deadlocking on something else outside of Indy. 这通常意味着您的服务器事件处理程序正在做他们不应该做的事情,通常是捕获和丢弃Indy的内部异常,与忙于终止服务器的线程上下文同步,或者对Indy之外的其他东西进行死锁。 Without seeing your actual code, there is no way to know for sure which is actually the case, but it is always user error that causes this kind of deadlock. 如果没有看到你的实际代码,就无法确定实际上是哪种情况,但始终是用户错误会导致这种死锁。

TIdAntiFreeze only affects Indy components that run in the context of the main thread. TIdAntiFreeze仅影响在主线程上下文中运行的Indy组件。 TIdTCPServer does not. TIdTCPServer没有。

I added this code on Form.OnClose works good! 我在Form.OnClose上添加了这段代码,效果很好!

procedure TformSFTP.FormClose(Sender: TObject; var Action: TCloseAction);
var
  iA : Integer;
  Context: TidContext;
begin
 if sftpServidorFTP.Active then
     with sftpServidorFTP.Contexts.LockList do
        try
           for iA := Count - 1 downto 0 do
           begin
              Context := Items[iA];
              if Context = nil then
                 Continue;
              Context.Connection.IOHandler.WriteBufferClear;
              Context.Connection.IOHandler.InputBuffer.Clear;
              Context.Connection.IOHandler.Close;
              if Context.Connection.Connected then
                 Context.Connection.Disconnect;
           end;
        finally
           sftpServidorFTP.Contexts.UnlockList;
        end;

if sftpServidorFTP.Active then

sftpServidorFTP.Active := False;

end; 结束;

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

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