【发布时间】:2011-03-19 21:31:26
【问题描述】:
我使用 Indy TIdhttp 组件构建了一个简单的网站监控应用程序。我想检测指定的页面何时没有在指定的时间范围内返回(我使用的是 5000 毫秒)。作为一个测试,我在一个网站上创建了一个页面,故意需要 15 秒来响应。但我无法让我的程序在 5 秒后“放弃”。我尝试了 ReadTimeout,suggested solution 使用计时器和 OnWorkBegin 事件(永远无法在获取后立即触发 OnWorkBegin称呼)。
注意我不担心连接超时。我关心的是服务器返回页面超时。
这是我一直在使用的一些源代码。它包含我引用的许多元素。
procedure TServLogic.WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
GetTimer.Enabled := True;
end;
procedure TServLogic.WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
GetTimer.Enabled := False;
end;
procedure TServLogic.GetTimerTimer(Sender: TObject);
begin
idHttp.Disconnect(True);
end;
procedure TServLogic.CallHttp(mlink: String): String;
begin
result := '';
GetTimer := TTimer.create(nil);
GetTimer.OnTimer := GetTimerTimer;
GetTimer.Interval := 5000;
try
IdHTTP := TIdHTTP.create(nil);
idhttp.ReadTimeout := 5000;
IdHttp.OnWorkBegin := WorkBegin;
IdHttp.OnWorkEnd := WorkEnd;
try
result := idhttp.get(mLink);
except
on e:exception do begin
AppendToLog('Server did not respond withing 5 seconds');
end;
end;
finally
GetTimer.Free;
idhttp.free;
end;
end;
【问题讨论】:
-
您的 TTimer 逻辑期望异步 TIdHTTP 不正确
-
查看了 Rob Kennedy 建议的文章。我创建了一个线程类型的解决方案。在主应用程序中创建了一个 TStringList 来管理我的线程。我还有一个每 5 秒触发一次的计时器。因此,如果我看到一个在 5 秒内没有“完成”的线程,我会调用该线程的 Terminate 方法。但这似乎并没有按照我想要的方式立即“终止”它;它似乎仍在等待。
-
要求线程自行终止不会真正起作用,因为 Indy 线程正在阻塞。他们不会检查他们是否被要求终止。相反,请尝试告诉连接断开连接。
-
好的 - 成功了!!!!感谢您的帮助和解决方案。但是 - 我怎样才能给你投票? (你从来没有正式回答过)。