题
我想从Internet下载文件,我想这应该是一项简单的任务。尝试几种不同的方法,我发现每个方法都有自己的缺点。主要问题是:
- 应用程序冻结,直到下载文件
- 如果Internet连接丢失/服务器未响应,则应用程序将永远冻结。
(细节:
如何通过HTTP从Internet检索文件?
连接从Internet下载文件时不会超时 )
因此,最后,我使用了从几个人那里得到的建议,使用了Indy等“ Pro”库。但是,Indy并不比我尝试过的代码要好得多(但是它要大得多且难以维护)。在使用Indy时,该应用程序并不仅在短时间内冻结,因此它仍然(某种程度上)可用。但是,在下载完成之前,无法关闭应用程序(如果互联网连接被打破,则永远不会)。
其他人报告了同样的问题: http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90
因此,为了使它起作用,我必须做一些黑客攻击?
另外,ConnectTimeOut属性未识别。
fIDHTTP := TIDHTTP.Create(NIL);
fIDHTTP.ConnectTimeout:=5000;
我应该放弃印地并返回到单独的线程中下载文件并在没有响应时结束该文件的原始想法(至少这样我摆脱了第三方库)?如果我这样做会有不可预见的副作用?
使用:Delphi 7,Indy 10.1.5 10.5(可能)。
谢谢
解决方案
解决这些问题并不难。您要做的第一件事是确保您处理错误处理。如果某事失败,请确保一切都正确清理。除此之外,请确保下载代码是单独线程的一部分。如果有任何问题,您总是可以从主程序中终止线程。这是对我有效的代码(仅用于下载,而不是线程)。
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;
其他提示
您可能需要以Indy方式使用Indy:使用线程。 Indy专门设计用于阻止模式,因为这是大多数Internet协议的工作方式(例如:使用HTTP,在协议级别,您发送请求,然后您阅读响应。您不会同时发送和接收)。 Tidantifreeze应该可以帮助您使用某些INDY功能而无需处理线程;我从来没有使用过,因为至少概念是一个丑陋的黑客。
如果不想处理线程,那么您应该看一下ICS( 链接到ICS主页 )。 IC被设计为在异步模式下使用,而无需线程。它不需要等效的tidantifreeze,因为它没有阻止。您开始下载,然后处理一些活动以获得进度和完成通知。 ICS与Indy一样是知名,专业和疯狂使用的。