停止Delphi Indy线程而不必等待超时Timeout

时间:2012-03-02 15:23:43

标签: multithreading delphi indy

这是我第一次使用Delphi处理多线程应用程序,所以对我来说仍然很好,但我读了很多。

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

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

这很烦人,特别是当我使用+200线程时。对于使用多线程和类似程序的其他软件,当我点击“停止”时,所有内容都会在几秒钟内停止,这就是我需要的。

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

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

提前感谢灯光:)

贝尼

2 个答案:

答案 0 :(得分:6)

课程TidHTTPOnWork个事件。使用此事件取消数据下载或上传。如何取消此活动?解雇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的阶段是随机的。事件可以在请求的中间,乞讨甚至结束时调用。上面的代码就像按下浏览器上的停止按钮一样。

[UPDATE] 忘了提一下,如果当线程被吊销出服务器的回复时没有调用OnWork事件,如果在指定的毫秒之前收到“最后一个响应”,则使用可以使用超时。请使用GetTickCount

答案 1 :(得分:2)

我使用Indy和webservices时遇到了类似的问题,我们所说的系统最多也是不可靠的(我必须为一些调用设置30分钟的读取超时)。

由于Rio Calls(以及您的IdHTTP)电话被阻止,您无法直接中断/中止。

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

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

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

我使用的是Delph 7和INDY10只是因为你的设置不同而已。

希望有所帮助

<强>顺便说一句

如果有人知道一种更好/更少有用的方法,我也很乐意看到它。