1

I wanna try something like download from a collection of image in a minimum of 3 concurrent download but, as soon as one of the 3 finished downloading add a new download from the list or must wait to add a new download until a download is finished from 3 concurrent download. How do I implement something like that?

So far I have tried this, but it seems to download all without waiting to be finished from at least 1 from the 3 concurrent download.

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);
        }));
user3666197
  • 1
  • 6
  • 50
  • 92
ropenrom24
  • 517
  • 8
  • 18
  • The `Parallel` class is not async-friendly. For limiting the amount of concurrent async I/O operations look [here](https://stackoverflow.com/questions/10806951/how-to-limit-the-amount-of-concurrent-async-i-o-operations). The `SemaphoreSlim` is probably the handiest tool for achieving asynchronous throttling. – Theodor Zoulias May 10 '20 at 10:41

1 Answers1

2

I'm not entirely sure you need to use Paralell.ForEach here, this answer can explain why better than me re-writing it here: https://stackoverflow.com/a/39796934/5326679

However, to answer your actual question, here's what I'd recommend:

var listOfLink = new List<string>();
var downloadTasks = listOfLink.Select(link => DownloadImageAsync(link));
await Task.WhenAll(downloadTasks);
xandermonkey
  • 4,054
  • 2
  • 31
  • 53
  • thanks does Task.WhenAll() download all? or you can set the minnimum download per task? – ropenrom24 May 10 '20 at 03:52
  • Awaiting the `Task.WhenAll()` call there will await all tasks to be completed. https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netcore-3.1 – xandermonkey May 10 '20 at 03:52
  • wow thanks this is just what I need. I think its better to not use `Parallel.ForEeach` for this situation but i'll try. – ropenrom24 May 10 '20 at 04:00
  • @ropenrom24 If you want to limit the number of concurrent downloads, just try `var semaphore = new SemaphoreSlim(3); var downloadTasks = listOfLink.Select(async link => { await semaphore.WaitAsync(); try { return await DownloadImageAsync(link); } finally { semaphore.Release(); } });`. – ckuri May 10 '20 at 06:41