随着Delphi 10.2.3的发布,随之带来更稳定、更完善的版本。今天借官方的例子,解读一下如何实现Http异步下载并显示下载进度。

使用的核心组件是THttpClient,首先建立一个THttpClient对象FClient,用他来执行下载任务。
procedure TFormDownloadDemo.FormCreate(Sender: TObject);
begin
FClient := THTTPClient.Create;
FClient.OnReceiveData := ReceiveDataEvent;
end;

我们看到,这里为FClient实现了OnReceiveData事件,目的用来显示下载进度,注意这个事件在异步执行Http下载时,是在线程中执行的。来看一下具体的实现代码:

procedure TFormDownloadDemo.ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64;
var Abort: Boolean);
var
LTime: Cardinal;
LSpeed: Integer;
begin
LTime := TThread.GetTickCount - FGlobalStart;//计算用时
LSpeed := (AReadCount * ) div LTime;//计算下载速度
TThread.Queue(nil,
procedure
begin
ProgressBarDownload.Value := AReadCount;//显示下载进度
LabelGlobalSpeed.Text := Format('Global speed: %d KB/s', [LSpeed div ]);//显示下载速度
end);
end;
AContentLength:下载内容的长度
AReadCount:已经下载的字节数
在这个事件中,计算每秒下载字节数,并用ProgressBarDownload可视组件来显示进度。
因为这个事件在线程中执行,所以同步界面上的ProgressBarDownload进度条时,用了TThread.Queue同步主线程。
 
接下来,实现具体的下载方法,并用一个按钮来执行这个方法,执行下载任务:
procedure TFormDownloadDemo.SampleDownload;
var
URL: string;
LResponse: IHTTPResponse;
LFileName: string;
LSize: Int64;
begin
LFileName := TPath.Combine(TPath.GetDocumentsPath, EditFileName.Text);//本地保存的文件地址
try
URL := EditURL.Text;//文件的URL地址 LResponse := FClient.Head(URL);//取得IHTTPResponse接口,通过该接口获得下载文件的长度
LSize := LResponse.ContentLength;//求出下载内容的长度
Memo1.Lines.Add(Format('Head response: %d - %s', [LResponse.StatusCode, LResponse.StatusText]));
LResponse := nil; ProgressBarDownload.Max := LSize;//设置进度条的最大值
ProgressBarDownload.Min := ;
ProgressBarDownload.Value := ;
LabelGlobalSpeed.Text := 'Global speed: 0 KB/s'; Memo1.Lines.Add(Format('Downloading: "%s" (%d Bytes) into "%s"' , [EditFileName.Text, LSize, LFileName])); // 建立一个文件流FDownloadStream,准备用于保存下载内容
FDownloadStream := TFileStream.Create(LFileName, fmCreate);//建立下载文件流
FDownloadStream.Position := ; FGlobalStart := TThread.GetTickCount;//取开始下载时间,用于计算下载速度 // 开始下载
FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream); finally
BStopDownload.Enabled := FAsyncResult <> nil;//下载过程中允许中止下载
BStartDownload.Enabled := FAsyncResult = nil;//下载完成后允许开始下载
end;
end;
上面对下载方法进行了注释,但还有必要说一下这个具体的下载调用所要实现的目的:
 
FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream);
 
我们看到,用FClient.BeginGet执行下载,同时传进去三个参数:
DoEndDownload:一个方法,下载完成后调用
URL:下载内容的URL
FDownLoadStream:保存下载内容的文件流。
 
重点在于DoEndDownload方法的实现:
procedure TFormDownloadDemo.DoEndDownload(const AsyncResult: IAsyncResult);
var
LAsyncResponse: IHTTPResponse;
begin
try
LAsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult);//通过传进来的参数,取得异步响应接口
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add('Download Finished!');
Memo1.Lines.Add(Format('Status: %d - %s', [LAsyncResponse.StatusCode, LAsyncResponse.StatusText]));
end);
finally
LAsyncResponse := nil;
FreeandNil(FDownloadStream);
BStopDownload.Enabled := False;
BStartDownload.Enabled := True;
end;
end;
首先这个方法,要声明成下面这样:
procedure (const ASyncResult: IAsyncResult);
然后我们看到,在具体的实现中,使用了传进来的参数ASyncResult,取得下载后接口LAsyncResponse,并通过该接口,进一步取得下载后的信息。
然后做的第二件事是释放保存下载的文件流FDownloadStream,最后设置开始下载按与中止下载按钮的状态。
同样,我们也看到,这里使用了TThread.Synchronize来同步界面,那说明这个方法也是在线程中执行的。
 
好了,在线程中下载文件并在界面上显示下载进度的整个过程基本就说完了。具体的例子代码在
C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\RTL\HttpAsyncDownload
这个例子是哪一个版本支持的,我也记不清,反正今天看到,全当10.2.3带的好了,其实这已不重要,重要的是,参考他来实现自己的http异步下载!
 
众所周知,这是一个跨平台的版本,同样的实现,可同时用于Android,IOS,Windows,OSX,Linux...这才是真正让人兴奋的事情。现在,我要集成到我的项目中去了...
 

Delphi10.2.3利用THttpClient实现http异步下载的更多相关文章

  1. 一个简单的利用 WebClient 异步下载的示例(一)

    继上一篇文章 一个简单的利用 HttpClient 异步下载的示例 ,我们知道不管是 HttpClient,还算 WebClient,都不建议每次调用都 new HttpClient,或 new We ...

  2. [.NET] 利用 async & await 的异步编程

    利用 async & await 的异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/5922573.html  目录 异步编程的简介 异 ...

  3. [.NET] 利用 async & await 进行异步 IO 操作

    利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html  序 上次,博主 ...

  4. 利用 async & await 的异步编程

    走进异步编程的世界 - 开始接触 async/await 利用 async & await 的异步编程 async 的三大返回类型 公司技术需求备忘录

  5. 教你50招提升ASP.NET性能(二十二):利用.NET 4.5异步结构

    (40)Take advantage of .NET 4.5 async constructs 招数40: 利用.NET 4.5异步结构 With the arrival of .NET 4.5, w ...

  6. 利用jquery.form实现异步上传文件

    实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...

  7. 一个简单的利用 WebClient 异步下载的示例(三)

    继续上一篇 一个简单的利用 WebClient 异步下载的示例(二) 后,继续优化它. 1. 直接贴代码了: DownloadEntry: public class DownloadEntry { p ...

  8. 一个简单的利用 WebClient 异步下载的示例(二)

    继上一篇 一个简单的利用 WebClient 异步下载的示例(一) 后,我想把核心的处理提取出来,成 SkyWebClient,如下: 1. SkyWebClient 该构造函数中 downloadC ...

  9. 一个简单的利用 HttpClient 异步下载的示例

    可能你还会喜欢 一个简单的利用 WebClient 异步下载的示例  ,且代码更加新. 1. 定义自己的 HttpClient 类. using System; using System.Collec ...

随机推荐

  1. 【11】ajax请求后台接口数据与返回值处理js写法

    $.ajax({ url: "/test.php",//后台提供的接口 type: "post",   //请求方式是post data:{"type ...

  2. 用C#做成的程序如何打包部署,在其他PC机运行

    刚刚接触C#,在linux下面做习惯了c和c++,在本机运行OK后,得瑟的去别的机子,居然运行不了,你妹啊,怎么回事,没有.NET Framework,原来和java类似,.NET Framework ...

  3. 手写web框架之加载Controller,初始化框架

    1,加载Controller     我们需要创建 一个ControllerHelper类,让它来处理下面的逻辑:      通过ClassHelper我们可以获取所有定义了Controller注解的 ...

  4. Java日志体系(六)log4j2

    1.1 简介 log4j2,一个日志的实现框架,是log4j的升级版本,于2014年7月正式亮相.与第一代log4j不同,log4j2完全重写了log4j的日志实现,并不是在原有基础上进行的升级,解决 ...

  5. js 笔记整理

    Js中for.for-in.forEach以及for-of的用法及特性对比 for-in for...in以任意顺序遍历一个对象的可枚举属性.所以for-in不适合用来迭代一个Array.同时,for ...

  6. MySQL安装Write configuration file 提示:configuration file template my.ini Error code-1

    在安装MySQL的时候, 在最后安装时,最后一步出现Write configuration file没成功勾选,并提示:configuration file template D:\mysql\my- ...

  7. python 删除文件或文件夹

    os.remove(path) 删除文件 path. 如果path是一个目录, 抛出 OSError错误.如果要删除目录,请使用rmdir(). remove() 同 unlink() 的功能是一样的 ...

  8. [转帖]PKI技术原理(收集 整理 归纳)

    PKI技术原理(收集 整理 归纳) https://blog.51cto.com/3layer/20430 总结归纳的 灰常好.. 7layer关注8人评论39427人阅读2007-03-14 11: ...

  9. HDU1285(拓扑排序裸题

    ..被多组测试坑了一波 #include<iostream> #include<vector> #include<queue> using namespace st ...

  10. PHP实现字母数字混合验证码

    一款简单的PHP实现字母数字混合验证码,支持自定义验证码.验证码图片.宽度.高度.个数.背景图片等 验证码调用地址:Application\Home\Controller\CodeController ...