【问题标题】:Stopping Delphi Indy threads without having to wait end Timeout停止 Delphi Indy 线程而无需等待结束超时
【发布时间】:2012-03-21 02:29:07
【问题描述】:

这是我第一次使用 Delphi 开发多线程应用程序,所以对我来说一切仍然很新鲜,但我读了很多。

我的线程很简单,简而言之,我只是使用 Indy (IdHTTP) 来获取网页的内容,然后验证内容是否包含字符串。这里没有问题。

现在,为了终止线程,我使用带有 WHILE DO 的布尔值。它似乎有效,但问题是:就像我在 Indy 中使用超时一样,有时我必须等待超时时间结束才能线程完成(例如,当服务器没有响应时)......

这很烦人,尤其是当我使用 +200 线程时。使用多线程和类似程序的其他软件,当我单击“停止”时,一切都会在几秒钟内停止,这就是我所需要的。

我读到我应该使用 AntiFreeze,以允许 IdHTTP “阅读我的指令”...

所以,我在这里有点迷路了。 我认为这不是很有必要,但这是我的代码:http://pastebin.com/G7De8bgb

提前感谢您的灯光:)

贝尼

【问题讨论】:

  • 为什么要停止 GET?你为什么要终止他们?不要靠近 TidAntiFreeze。
  • 例如如果进程太长。我希望能够随时中止该程序。就像“杀死”线程一样,但当然是以安全的方式。谢谢。贝尼

标签: multithreading delphi indy


【解决方案1】:

TidHTTP 类有一个OnWork 事件。使用此事件取消数据下载或上传。如何取消此活动?触发 Abort 静默异常。

这是一个伪代码:

THTTPThread = class(TThread)
    private
        HTTPComponent: TidHTTP;
        procedure OnHTTPProgress(ASender: TObject; AWorkMode: TWorkMode;
                                     AWorkCount: Int64);
    published
        procedure execute();
end;

implementation
procedure THTTPThread.execute;
begin
    Self.HTTPComponent := TidHTTP.Create(nil);
    with HTTPComponent do
    begin
        OnWork := Self.OnHTTPProgress;
        Get('http://www.google.com');
    end;
end;

procedure THTTPThread.OnHTTPProgress(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
begin

    if Self.Terminated then
        Abort;
end;

考虑到调用 OnWork 的阶段是随机的。可以在请求的中间、请求时甚至结束时调用该事件。上面的代码就像你按下浏览器上的停止按钮一样工作。

[更新] 忘了提一下,如果在线程挂出等待服务器回复时没有调用 OnWork 事件,如果在指定的毫秒前收到“最后一个响应”,则使用可以使用超时。为此使用GetTickCount

【讨论】:

  • 啊,真有趣!我会试一试。感谢您的输入。贝尼
  • 所以,自从我第一次发帖以来,我将 Indy 更改为 ip*Works。一切都保持不变,我只是尝试实现HTTP.Interrupt;。因此,当单击停止时,我中止了新线程的创建,但我不知道我可以将代码放在哪里来中断已经启动的线程...
  • 经过长时间的研究,您似乎找到了正确的解决方案。再次感谢你 !最好的。贝尼 ;)
  • @ChristopherRamírez - OnHTTPProgress 中谁在中止?
  • @SolarWind: Abort()SysUtils 单元中的一个函数。 See documentation.
【解决方案2】:

我在使用 Indy 和 web 服务时遇到了类似的问题,我们正在讨论的系统充其量也是不可靠的(我不得不为某些调用设置 30 分钟的读取超时)。

由于 Rio Calls(和您的 IdHTTP )调用阻塞了您不能直接取消/中止它们。

但是,您可以(如果使用不同的线程)断开底层套接字,这将导致 get/webcall 中的异常。

我已经做了一个快速破解,只使用 TIdHTTP 来测试这个想法,它似乎和 Rio 一样工作。

在您的主/控制线程中,您需要调用 IDHTTP.Disconnect,然后捕获将在您的线程中引发的异常。通过查看您在 Thread.Execute 中创建 IdHTTP 的代码,您必须将其声明移动到类的构造函数中,以允许线程类上的 Abort 函数简单地断开套接字。

我已经使用了 Delph 7 和 INDY10,只是因为这与您的设置不同。

希望有帮助

顺便说一句

如果有人知道更好/不那么激进的方法,我也很乐意看到。

【讨论】:

  • 感谢您提出断开 IdHTTP 连接的想法。只是我有点关于在哪里放置已经启动的代码断开线程:s Beny
猜你喜欢
  • 2017-09-27
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 2012-07-13
  • 2021-05-03
  • 2021-11-03
  • 1970-01-01
  • 2013-02-03
相关资源
最近更新 更多