【发布时间】:2018-05-19 03:28:47
【问题描述】:
我使用 Delphi 10.2 Tokyo 和 Indy(集成版)。
场景: 我在线程中执行 http GET 请求(TIdHttp),并使用代理。 有时,代理似乎会导致 Indy 不超时,也不从 GET 中返回。 我还分配 onWork 事件处理程序以响应 Abort 按钮并在此处理程序中调用 idHttp.Disconnect 函数。当GET似乎被冻结时,中止也不起作用,可能在这种情况下没有触发onWork事件,我不知道。
主线程是空闲的,只创建了 50 个线程,每个线程都通过其 TIdHttp 实例执行 GET。 Ans sometiumes,正如我所提到的,GET 不返回的代理原因导致“挂起”线程。
我的问题是:如何从外部线程强制 Indy 中止?当GET拒绝返回时,有什么可以通过代码做的吗?
【问题讨论】:
-
首先,您是否分配了一个非无限的
ReadTimeout?不要在OnWork事件中调用Disconnect。改为引发异常,例如调用SysUtils.Abort。但是如果连接被挂起/阻塞,OnWork事件将不会被触发。您的主线程可以直接调用Disconnect以中止另一个线程中正在进行的阻塞套接字操作,但这不是可移植的(它适用于 Windows,可能不适用于其他平台) -
@Remy Lebeau:我将超时设置为 30 秒,但是当 GET 被“冻结”时它也不会触发。我使用 firemonkey,所以它需要在 Win32/Win64 和 macOS 上工作。我刚刚遇到了另一个问题,相同的,只是没有使用代理,所以它不是由于代理。我对一个网站做了一个 GET,其中包含要处理的数据作为 url 的参数。处理数据的服务器需要 2 分钟才能响应。在这种情况下,GET 也被“冻结”,我的用户无法中止,因为在 GET 返回的“等待”期间不会触发 onWork。
-
ReadTimeout应该可以工作,假设连接实际上是空闲的,而不仅仅是缓慢地发送数据。如果它不起作用,则必须对其进行调试以找出原因。从不同的线程调用Disconnect可能是你最好的选择。