Delphi 另一种TIdTCPServer死锁情况
我遇到了一个已知的问题:IdTCPServer在尝试停用它时挂起。我读过很多关于这个问题的文章,我意识到僵局正在发生。但我很难理解到底是哪种代码导致了问题。我的应用甚至没有窗口,所以对VCL组件的同步调用不是原因。有两个事件处理程序OnConnect和OnExecute。问题出现在OnConnect中。代码:Delphi 另一种TIdTCPServer死锁情况,delphi,deadlock,delphi-xe,indy,Delphi,Deadlock,Delphi Xe,Indy,我遇到了一个已知的问题:IdTCPServer在尝试停用它时挂起。我读过很多关于这个问题的文章,我意识到僵局正在发生。但我很难理解到底是哪种代码导致了问题。我的应用甚至没有窗口,所以对VCL组件的同步调用不是原因。有两个事件处理程序OnConnect和OnExecute。问题出现在OnConnect中。代码: TMyServer = class ... private FServer: TIdTCPServer; ... end; TMyServer.ServerConnect(AContex
TMyServer = class
...
private
FServer: TIdTCPServer;
...
end;
TMyServer.ServerConnect(AContext...); //onconnect
begin
try
if not Condition then
begin
...
AContext.Connection.Disconnect;
Stop;
end
else Start;
except
on E: Exception do
if E is EIdException then raise;
...
end;
TMyServer.Start;
begin
...
FServer.active := true;
FServer.StartListening;
...
end;
TMyServer.Stop;
begin
...
FServer.StopListening;
FServer.Active := false;
...
end;
TMyServer.ServerExecute(AContext...); //onexecute
begin
LLine := AContext.Connection.IOHandler.ReadLn;
case (LLine) of
...
end;
end;
ServerExecute的代码非常庞大,所以我不会在这里发布。此外,我想问题不在其中。当客户端连接到服务器且条件为false时,服务器尝试断开此客户端的连接,并挂起行
FServer.Active:=false代码>
我已经从代码中排除了所有日志记录(我认为问题在于线程对日志文件的访问)。因此,在事件处理程序中,只有计算,而没有任何东西会导致死锁)。我读过关于重新提出印地岛例外情况的报道,但这对我也没有帮助。
如果您能提供任何帮助和解释,我将不胜感激,因为我认为我不完全理解这种情况的目的。您正试图从服务器的事件处理程序中停用服务器。这就是代码死锁的原因
将Active
属性设置为False将终止所有正在运行的客户端线程,并等待它们完全终止。在这些线程的上下文中触发OnConnect
、OnDisconnect
和OnExecute
事件。因此,最终会出现一个线程,该线程试图自行等待并死锁
要使服务器安全地自行停用,必须异步执行,例如使用TIdNotify
类,例如:
uses
..., IdSync;
TMyServer.ServerConnect(AContext...); //onconnect
begin
try
if not Condition then
begin
...
AContext.Connection.Disconnect;
TIdNotify.NotifyMethod(Stop);
end
else
TIdNotify.NotifyMethod(Start);
except
on E: Exception do
if E is EIdException then raise;
...
end;
end;
顺便说一句,您不需要手动调用StartListening()
和StopListening()
方法。活动属性设置器在内部为您完成此操作。非常感谢Remy。你的回答让我明白了一切。