TidCustomTCPServer.Active := 错误,从不 returns
TidCustomTCPServer.Active := False, never returns
我从 Indy 10 TIdTCPServer 下载了一些有趣的代码并编译并 运行 它。它有点乱,它可能需要工作,但它是有趣的东西的良好基础。至少我不必 post 这里的所有代码。不管怎样,我决定先去激活 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
,所以我不得不修改那里的代码以获取消息:
"Operation Aborted"
之后我进一步追踪,但代码执行最终回到同一个异常处理程序。
这是一个错误还是永远不要将 Active 属性 设置为 False 更好?在我的测试中,如果我关闭应用程序并让 RTL 管理所有释放。无限循环没有发生(应用程序确实关闭)
异常是正常行为。
Indy 使用阻塞套接字。
TIdListenerThread
运行一个循环等待客户端连接。每次等待都是一次阻塞操作。
当服务器停用时,它会关闭其侦听套接字,导致挂起的套接字操作中止,然后侦听线程终止。中止异常在内部处理。
服务器的析构函数也设置了Active=False
,所以无论你是否显式停用,服务器都会被停用。
这本身并不会导致您挂起。通常,设置 Active=False
挂起的唯一方法是服务器事件处理程序尝试同步与主 UI 线程同步,而主线程被阻止等待服务器停用。经典死锁场景。
不过,在您链接到的演示中情况似乎并非如此(唯一使用的同步是异步的)。因此,您的调试尚未揭晓的其他事情可能正在发生。应该不会挂。
我从 Indy 10 TIdTCPServer 下载了一些有趣的代码并编译并 运行 它。它有点乱,它可能需要工作,但它是有趣的东西的良好基础。至少我不必 post 这里的所有代码。不管怎样,我决定先去激活 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
,所以我不得不修改那里的代码以获取消息:
"Operation Aborted"
之后我进一步追踪,但代码执行最终回到同一个异常处理程序。
这是一个错误还是永远不要将 Active 属性 设置为 False 更好?在我的测试中,如果我关闭应用程序并让 RTL 管理所有释放。无限循环没有发生(应用程序确实关闭)
异常是正常行为。
Indy 使用阻塞套接字。
TIdListenerThread
运行一个循环等待客户端连接。每次等待都是一次阻塞操作。
当服务器停用时,它会关闭其侦听套接字,导致挂起的套接字操作中止,然后侦听线程终止。中止异常在内部处理。
服务器的析构函数也设置了Active=False
,所以无论你是否显式停用,服务器都会被停用。
这本身并不会导致您挂起。通常,设置 Active=False
挂起的唯一方法是服务器事件处理程序尝试同步与主 UI 线程同步,而主线程被阻止等待服务器停用。经典死锁场景。
不过,在您链接到的演示中情况似乎并非如此(唯一使用的同步是异步的)。因此,您的调试尚未揭晓的其他事情可能正在发生。应该不会挂。