Delphi /赛车.程序长时间延迟



我的应用程序在调用过程TIdStackWindows.Connect时挂起。当TCP/IP地址存在时没有问题,但如果不存在,我就会感到困惑。IP地址是一个文字-不涉及DNS查找。我期待在超时(TCPClient.ConnectTimeout)后连接尝试失败,我设置了1秒,但应用程序在此调用上挂起长达30秒(来自我的应用程序的调用不是线程)。我打算将TCP连接移动到一个线程,但长连接超时仍然是一个问题)。

如果我在Delphi IDE中暂停执行,当应用程序无响应时,我被定位在:

ntdll.KiUserApcDispatcher:
7C90E450 8D7C2410         lea edi,[esp+$10]

然后按F8几次,直到看到堆栈帧。我那时在:

IdStack.TIdStack.RaiseSocketError(10038)
IdStack.TIdStack.RaiseLastSocketError
IdStack.TIdStack.CheckForSocketError(-1)
IdStackWindows.TIdStackWindows.Connect(912,'10.8.2.170',5001,Id_IPv4)
IdSocketHandle.TIdSocketHandle.Connect
IdIOHandlerStack.TIdConnectThread.Execute
:00451fc1 HookedTThreadExecute + $2D
Classes.ThreadProc($254B910)
System.ThreadWrapper($5456CB0)
:00451ea3 CallThreadProcSafe + $F
:00451f10 ThreadExceptFrame + $3C
:7c80b729 ; C:WINDOWSsystem32kernel32.dll

我注意到,经过一番探索,这个话题已经收到了一些流量。常见的答案似乎是"把它放在一条线里"。我有这个打算,但是超时时间太长还是会有问题。为什么连接超时不工作?我正在使用Indy 10.5.5和Delphi 2006 -如果我升级到最新版本的Indy会有很多迁移?

阻塞套接字在API层没有连接超时的概念,因此Indy的ConnectTimeout是手动实现的超时。Indy在内部工作线程中调用TIdStack.Connect(),而TIdTCPClient.Connect()运行一个等待该线程终止的睡眠循环。如果循环检测到ConnectTimeout周期已过,它将关闭套接字,这应该会导致阻塞的TIdStack.Connect()立即退出,但这并不能保证。创建和终止线程也有操作系统开销。它绝对不应该用30秒来对1秒的超时做出反应,但另一方面,1秒通常太小了。线程甚至可能在1秒内都不会开始运行。通常应该将ConnectTimeout设置为至少5-10秒,以便给操作系统足够的时间来完成其工作。

最新更新