【问题标题】:How to implement download queue async with parallel foreach如何使用并行 foreach 实现下载队列异步
【发布时间】:2020-05-10 13:10:10
【问题描述】:

我想尝试在至少 3 个并发下载中从一组图像下载,但是,一旦 3 个完成下载中的一个从列表中添加新下载,或者必须等待添加新下载直到下载从 3 个并发下载完成。我该如何实现这样的东西?

到目前为止,我已经尝试过这个,但它似乎从 3 个并发下载中的至少 1 个下载完成而无需等待完成。

List<string> listOfLink = new List<string>();

await Task.Run(() =>
        Parallel.ForEach(listOfLink, new ParallelOptions { MaxDegreeOfParallelism = 3 }, async (link, state, index) => 
        {
          //Download image httpclient
          //DownloadImageAsync(link);
        }));

【问题讨论】:

  • Parallel 类不是异步友好的。要限制并发异步 I/O 操作的数量,请查看 hereSemaphoreSlim 可能是实现异步限制的最方便的工具。

标签: c# async-await concurrent-processing


【解决方案1】:

我不完全确定你需要在这里使用Paralell.ForEach,这个答案可以解释为什么比我在这里重写它更好:https://stackoverflow.com/a/39796934/5326679

但是,要回答您的实际问题,我建议您这样做:

var listOfLink = new List<string>();
var downloadTasks = listOfLink.Select(link => DownloadImageAsync(link));
await Task.WhenAll(downloadTasks);

【讨论】:

  • 感谢 Task.WhenAll() 是否全部下载?或者您可以设置每个任务的最小下载量?
  • 等待Task.WhenAll() 调用将等待所有任务完成。 docs.microsoft.com/en-us/dotnet/api/…
  • 哇,谢谢,这正是我所需要的。我认为在这种情况下最好不要使用Parallel.ForEeach,但我会尝试。
  • @ropenrom24 如果你想限制并发下载数,试试var semaphore = new SemaphoreSlim(3); var downloadTasks = listOfLink.Select(async link =&gt; { await semaphore.WaitAsync(); try { return await DownloadImageAsync(link); } finally { semaphore.Release(); } });
猜你喜欢
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2021-05-30
  • 2013-08-25
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多