Junior222
Junior222

Reputation: 833

Asynchronous downloading files in C#

I have a question about asynchronous operations in C#. Suppose I have some code like this:

public async void Download(string[] urls)
{
    for(int i = 0; i < urls.Length; i++);
    {
        await DownloadHelper.DownloadAsync(urls[i], @"C:\" + i.ToString() + ".mp3");
    }
}

But this code does not really download files asynchronously. It begins to download the file from the first URL and then awaits this operation. It then begins to download the file from the second URL... and so on.

Thereby files are downloaded one by one, and I would like to get them started downloading simultaneously.

How could I do it?

Upvotes: 1

Views: 4359

Answers (2)

spender
spender

Reputation: 120450

Rather than awaiting individual tasks, create the tasks without waiting for them (stick them in a list), then await Task.WhenAll instead...

public async void Download(string[] urls)
{
    //you might want to raise the connection limit, 
    //in case these are all from a single host (defaults to 6 per host)
    foreach(var url in urls)
    {
        ServicePointManager
            .FindServicePoint(new Uri(url)).ConnectionLimit = 1000;
    }
    var tasks = urls
         .Select(url =>
             DownloadHelper.DownloadAsync(
                 url,
                 @"C:\" + i.ToString() + ".mp3"))
         .ToList();
    await Task.WhenAll(tasks);
}

Upvotes: 4

i3arnon
i3arnon

Reputation: 116548

When you say asynchronous you mean concurrent, these are not the same. You can use Task.WhenAll to await for all asynchronous operations at the same time:

public async Task Download(string[] urls)
{
    var tasks = new List<Task>();
    for(int i = 0; i < urls.Length; i++);
    {
        tasks.Add(DownloadHelper.DownloadAsync(urls[i], @"C:\" + i.ToString() + ".mp3"));
    }

    await Task.WhenAll(tasks);
}

You should also refrain from using async void unless in an event handler

Upvotes: 9

Related Questions