6

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

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

(细节:

如何通过 HTTP 从 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 并返回在单独的线程中下载文件并在线程没有响应时结束线程的原始想法(至少这样我摆脱了第 3 方库)?如果我这样做,会有无法预料的副作用吗?

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

谢谢

4

2 回答 2

4

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

如果你不想处理线程,那么你应该看看ICS——它被设计为在异步模式下使用,没有线程。它不需要等价物,TIdAntiFreeze因为它没有阻塞。您开始下载并处理一些事件以获取进度和完成通知。ICS 与 Indy 一样知名、专业和广泛使用。

于 2010-07-07T09:57:13.690 回答
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;
于 2010-07-06T20:49:11.787 回答