多线程WinHttp下载

Hzm*_*zmy 5 delphi multithreading winhttp omnithreadlibrary

我正在创建一个Delphi应用程序来从Internet下载文件,如果服务器支持范围请求它将是多线程的.进度也被转发回GUI.

当前的软件模型使用TThread组件.GUI调用a TDownloadThread然后生成TDownloadPartThreads- 这些是实际通过'WinHttp'进行下载的线程.

我的问题:CPU已用完,即使只下载4个线程的下载.

我的假设原因:

  1. 我每8192字节写一次目标文件,想知道在写入一个块之前是否应该缓冲它?
  2. 线程通信是通过Synchronize(MainForm.UpdateProgress(Downloaded, TotalSize))我听到的AWFUL来完成的,也许我应该在线程之间共享一个对象,这样我可以使用主窗体上的计时器来访问它,以更新进度?

我的解决方案

  1. 交错文件写入只写每个x字节.

  2. 更新TThread要使用的组件,OmniThreadLibrary并以某种方式将数据发送回主表单.TDownloadPart然后,每个线程将成为一个IOmniWorker并通过与主表单共享对象来发回其进度.然后,主窗体将使用计时器来更新其进度,如:ProgressBar1.Position := sharedDataObject.Progress;

希望有人可以指出我正确的方向!

gab*_*abr 2

我将使用共享对象来更新状态 - 就像您在第二个解决方案中建议的那样。如果您只共享 8 字节(4 个字节不够!)文件大小,并且确保每个共享位置的地址是 8 对齐的,则可以使用互锁指令来修改此共享状态,并且不需要锁定。

维护共享状态的最简单方法是来自GpStuff单元的 TGp8AlignedInt64 记录,它同样适用于基于 OmniThreadLibrary 或 TThread 的解决方案。

TGp8AlignedInt64 = record
  function  Add(value: int64): int64; inline;
  function  Addr: PInt64; inline;
  function  CAS(oldValue, newValue: int64): boolean;
  function  Decrement: int64; overload; inline;
  function  Decrement(value: int64): int64; overload; inline;
  function  Increment: int64; overload; inline;
  function  Increment(value: int64): int64; overload; inline;
  function  Subtract(value: int64): int64; inline;
  property Value: int64 read GetValue write SetValue;
end; 
Run Code Online (Sandbox Code Playgroud)

对此记录的所有操作都是线程安全的,因此您可以安全地在工作线程中执行 .Add 操作,并同时从主窗体中的计时器事件中调用 .Value 。