【问题标题】:Delphi TIdHttp with proxy sometimes no timeout and a GET does not return带有代理的 Delphi TIdHttp 有时没有超时并且 GET 不返回
【发布时间】: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 可能是你最好的选择。

标签: delphi indy


【解决方案1】:

我通过使用后台线程断开套接字并实现超时解决了我的问题,即使套接字被“冻结”并且未触发 onWork,这似乎也可以工作。 为此,我将创建的 TIdHttp 实例以及创建实例的时间添加到数组中。如果 GET 返回正常,则数组条目将被删除。在后台线程中,我检查用户是否单击了中止,然后循环遍历数组并在每个实例上调用断开连接。如果达到超时期限,我还会检查同一个线程,并调用断开连接。 可能不是完美的解决方案,但它对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2019-04-26
    • 2022-11-11
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多