维护 N 个并发 HTTP 下载

发布于 2024-09-26 07:15:01 字数 211 浏览 0 评论 0原文

我有一个按日期范围查询 Web 服务的应用程序。 Web 服务返回 GUID 列表。然后,我获取每个 GUID 并下载它对应的 WAV 文件。现在我一项一项地做,效果很好。我想做的是同时下载最多 N 个 WAV 文件。由于某种原因,我无法掌握完成此任务的好方法。

我使用 IP*Works(n/软件)TipwHTTP(异步)组件。

任何人有任何建议可以推动我朝正确的方向发展。

I have an application that queries a web service by a date range. The web service returns a list of GUID's. I then take each GUID and download a WAV file that it corresponds too. Right now I do it one by one and works fine. What I would like to do is download up to N number of WAV files simultaneously. For some reason I just can not grasp a good way to accomplish this.

I use IP*Works (n/Software) TipwHTTP(async) component.

Anyone have any suggestions to push me in the right direction.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽袖吟 2024-10-03 07:15:01

将每个下载放在单独的线程中并管理该下载列表。例如,您可以使用 OmniThreadLibrary 来简化线程编程。您还可以在 Cromis 查看我的线程单元,它要简单得多,但是对于你的情况来说可能就足够了。它非常容易使用。

如果您不喜欢线程,您还可以创建一个 exe,在启动时获取输入参数并将内容下载到指定位置。

请注意,同时下载多个文件可能仅在您从不同来源下载时才有帮助,否则您仍然会受到唯一来源的带宽的限制,并且还会有线程开销。

下面是我的线程单元和 Indy for HTTP 的代码,仅作为示例,因为它很容易理解:

procedure TfMain.FormCreate(Sender: TObject);
var
  Task: ITask;
begin
  FTaskPool.DynamicSize := cbDynamicPoolSize.Checked;
  FTaskPool.MinPoolSize := StrToInt(ePoolSize.Text);
  FTaskPool.OnTaskMessage := OnTaskMessage;
  FTaskPool.Initialize;

  for I := 1 to NumberOfDownloads do
  begin
    Task := FTaskPool.AcquireTask(OnTaskExecute, 'HTTPDownload');
    Task.Values.Ensure('TargeFile').AsString := aFileName;
    Task.Values.Ensure('URL').AsString := aDownloadURL;
    Task.Run;
  end;
end;

procedure TfMain.OnTaskExecute(const Task: ITask);
var
  HTTPClient: TIdHTTP;
  FileStream: TFileStream;
begin
  HTTPClient := TIdHTTP.Create(nil);
  try
    FileStream := TFileStream.Create(Task.Values.Get('TargeFile').AsString, fmCreate);
    try
      HTTPClient.Get(Task.Values.Get('URL').AsInteger, FileStream);
      Task.Message.Ensure('Result').AsString := 'Success';
      Task.SendMessageAsync;
    finally
      FileStream.Free;
    end;   
  finally
    HTTPClient.Free;
  end;
end;

procedure TfMain.OnTaskMessage(const Msg: ITaskValues);
begin
  // do something when a single download has finished
end;

Put each download in a separate thread and manage that list of downloads. You can use OmniThreadLibrary for instance to ease the thread programming. You can also look at my threading unit at Cromis which is a lot simpler but it may be enough for your case. It is very easy to use.

If you dislike threads you can also make an exe that takes input params when started and downloads the content to a specified location.

Just note that downloading many files simultaniously will only probably help if you download from different sources, if not you will still be limited by the bandwith of your only source and also have a threading overhead on you.

Here is a code with my threading unit and Indy for HTTP, just for example because it is easy to understand:

procedure TfMain.FormCreate(Sender: TObject);
var
  Task: ITask;
begin
  FTaskPool.DynamicSize := cbDynamicPoolSize.Checked;
  FTaskPool.MinPoolSize := StrToInt(ePoolSize.Text);
  FTaskPool.OnTaskMessage := OnTaskMessage;
  FTaskPool.Initialize;

  for I := 1 to NumberOfDownloads do
  begin
    Task := FTaskPool.AcquireTask(OnTaskExecute, 'HTTPDownload');
    Task.Values.Ensure('TargeFile').AsString := aFileName;
    Task.Values.Ensure('URL').AsString := aDownloadURL;
    Task.Run;
  end;
end;

procedure TfMain.OnTaskExecute(const Task: ITask);
var
  HTTPClient: TIdHTTP;
  FileStream: TFileStream;
begin
  HTTPClient := TIdHTTP.Create(nil);
  try
    FileStream := TFileStream.Create(Task.Values.Get('TargeFile').AsString, fmCreate);
    try
      HTTPClient.Get(Task.Values.Get('URL').AsInteger, FileStream);
      Task.Message.Ensure('Result').AsString := 'Success';
      Task.SendMessageAsync;
    finally
      FileStream.Free;
    end;   
  finally
    HTTPClient.Free;
  end;
end;

procedure TfMain.OnTaskMessage(const Msg: ITaskValues);
begin
  // do something when a single download has finished
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文