Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 停用时Indy TCP服务器冻结_Delphi_Delphi Xe2_Deadlock_Indy_Indy10 - Fatal编程技术网

Delphi 停用时Indy TCP服务器冻结

Delphi 停用时Indy TCP服务器冻结,delphi,delphi-xe2,deadlock,indy,indy10,Delphi,Delphi Xe2,Deadlock,Indy,Indy10,我有一个Indy ServerTIdTCPServer,它有3个不同端口的绑定。如果我将一个客户端连接到这3个端口,然后停用服务器,它就会陷入死锁。无论我做什么,它都不会响应我的点击,甚至不会向Windows报告“无响应”。如果在停用服务器之前断开客户端的连接,一切都会很顺利。我的意思是在Server.Active:=False中“停用” 还有其他人经历过吗?是什么引起的?我在这里没有发生任何跨越线程的事情,这可能会导致死锁(例如GUI更新)。我试过一种防冻液成分tid防冻液,但没有成功 TId

我有一个Indy Server
TIdTCPServer
,它有3个不同端口的绑定。如果我将一个客户端连接到这3个端口,然后停用服务器,它就会陷入死锁。无论我做什么,它都不会响应我的点击,甚至不会向Windows报告“无响应”。如果在停用服务器之前断开客户端的连接,一切都会很顺利。我的意思是在
Server.Active:=False中“停用”


还有其他人经历过吗?是什么引起的?我在这里没有发生任何跨越线程的事情,这可能会导致死锁(例如GUI更新)。我试过一种防冻液成分
tid防冻液
,但没有成功

TIdTCPServer
是一个多线程组件。服务器停用期间的死锁意味着其一个或多个客户端线程没有正确终止。这通常意味着您的服务器事件处理程序正在执行一些不应该执行的操作,通常是捕获和丢弃Indy自身的内部异常,与忙于终止服务器的线程上下文同步,或者在Indy之外的其他操作上死锁。如果看不到实际的代码,就无法确定实际情况是什么,但导致这种死锁的总是用户错误


tid防冻液
仅影响在主线程上下文中运行的Indy组件。TIdTCPServer没有。

我在表单中添加了此代码。OnClose工作正常


结束

如果没有连接会发生什么情况?它是否正确停用?如果是这样,请在停用服务器之前尝试终止来自客户端的连接。是的,如果没有更多客户端连接,它将成功停用。TIdTCPServer的
Active
属性设置器会自动断开任何活动客户端连接。但它还必须等待这些线程终止,如果这些线程没有正确终止(通常是由于事件处理程序代码中的用户错误),就会发生这种死锁。我们需要查看Jerry的实际代码。谢谢@Remy,因为我正在Indy's
TIdCustomTCPServer.TerminateAllThreads
。。。除非“雷博”是其他人证明你知道你在说什么,那就是我。我是Indy开发团队的一员。我知道如果不看我的代码,问题是无法被精确定位的,我仍在寻找问题的原因。这至少帮助我了解了我应该在哪里寻找。我找到了源头,这是一个内存泄漏,我也在努力寻找。一旦这个漏洞被修复,这个问题也被修复了。此内存泄漏在一个客户端线程内。 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;