TidCustomTCPServer.Active:= False,永不返回

时间:2018-01-31 06:03:33

标签: delphi indy

我从Indy 10 TIdTCPServer下载了一些有趣的代码并编译并运行它。它有点乱,它可能需要工作,但它是一个有趣的东西的良好基础。至少我不必在这里发布所有代码。无论如何,我决定首先取消激活ExampleServer,而不是仅仅在OnDestroy中释放。所以我补充道:

procedure TServerPushExampleForm.FormClose(Sender: TObject);
begin
  ExampleServer.Active := False; // bug here - never returns
end;

为了尝试对此进行调试,我将 IdCustomTCPServer.pas 添加到项目中并进入该项目。

TIdCustomTCPServer.StopListening;LListener.WaitFor;引发异常此异常被TIdListenerThread.Run;中的异常处理程序所困,但E.message未在此处检索到,所以我不得不修改那里的代码来获取消息:

“操作已中止”

之后我进一步追踪它,但代码执行最终会回到同一个异常处理程序。

这是一个错误还是永远不要将Active属性设置为False?在我的测试中,如果我关闭应用程序并让RTL管理所有免费提供。无限循环不会发生(应用确实关闭)

1 个答案:

答案 0 :(得分:3)

例外是正常行为。

Indy使用阻塞套接字。

TIdListenerThread运行循环,等待客户端连接。每次等待都是阻止操作。

当服务器被停用时,它会关闭其侦听套接字,导致挂起的套接字操作中止,然后终止侦听线程。中止异常在内部处理。

服务器的析构函数也设置Active=False,因此无论是否显式停用,服务器都将被停用。

这个,如果它本身,不会导致你的挂起。通常,设置Active=False的唯一方法是挂起,如果服务器事件处理程序尝试同步地与主UI线程同步,而主线程被阻塞等待服务器停用。经典的死锁场景。

但是在您链接的演示中似乎并非如此(所使用的唯一同步是异步的)。所以,还有其他事情可能会发生,你的调试尚未揭晓。应该没有挂起。