使用Indy时连接不会超时

时间:2010-07-06 15:04:54

标签: delphi indy10

我想从互联网上下载文件,我想这应该是一个简单的任务。尝试了几种不同的方法,我发现每种方法都有自己的缺点。 主要问题是:

  • 应用程序冻结,直到下载文件
  • 如果Internet连接丢失/服务器没有响应,应用程序将永久冻结。

(详见:

How to retrieve a file from Internet via HTTP?
The connection does not timeout while downloading file from internet

所以,最后我使用了我从几个人那里得到的建议来使用像Indy这样的“专业”库。但是,Indy并没有比我尝试过的代码要好得多(但它更大,难以维护)。使用Indy时,应用程序不会仅在短时间内冻结,因此它仍然(某种程度上)可用。但是,在下载完成之前无法关闭应用程序(从不会因为Internet连接中断而关闭)。

其他人报告了同样的问题:http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90

那么,为了让它发挥作用,我必须对TIDAntiFreeze进行一些黑客攻击?

此外,无法识别ConnectTimeout属性。

fIDHTTP := TIDHTTP.Create(NIL);
fIDHTTP.ConnectTimeout:=5000;

我应该放弃Indy并回到最初在单独的线程中下载文件的想法,并在它没有响应时结束线程(至少这样我摆脱了第三方库)?如果我这样做会有不可预见的副作用吗?

使用:Delphi 7,Indy 10.1.5 10.5(可能)。

由于

2 个答案:

答案 0 :(得分:4)

您可能需要使用Indy方式:使用线程。 Indy专门设计用于阻塞模式,因为这是大多数Internet协议的工作方式(例如:使用HTTP,在协议级别,您发送请求然后您阅读响应。您不会同时发送和接收)。 TIdAntiFreeze应该可以帮助您使用一些Indy功能而无需处理线程;我从来没有用过,因为,至少在概念上,这是一个丑陋的黑客。

如果不想处理线程,那么你应该看一下ICS(link to ICS home page)。 ICS设计用于异步模式,无需线程。它不需要相当于TIdAntiFreeze,因为它没有阻塞。您开始下载并处理一些事件以获取进度和完成通知。 ICS与Indy一样着名,专业且广泛使用。

答案 1 :(得分:0)

解决这些问题并不困难。您要做的第一件事是确保您已正确处理错误处理。如果出现故障,请确保一切正常清理。除此之外,请确保下载代码是单独线程的一部分。如果有任何问题,您可以随时终止主程序中的线程。这是代码(仅用于下载,而不是线程),对我来说工作正常。

with TDownloadURL.Create(nil) do
  try
    URL := 'myurltodownload.com';
    filename := 'locationtosaveto';
    try
      ExecuteTarget(nil);
    except
      result := false;
    end;
    if not FileExists(filename) then
      result := false;
  finally
    clear;
    free;
  end;