Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
713 views
in Technique[技术] by (71.8m points)

c# - AWAIT multiple file downloads with DownloadDataAsync

I have a zip file creator that takes in a String[] of Urls, and returns a zip file with all of the files in the String[]

I figured there would be a number of example of this, but I cannot seem to find an answer to "How to download many files asynchronously and return when done"

How do I download {n} files at once, and return the Dictionary only when all downloads are complete?

private static Dictionary<string, byte[]> ReturnedFileData(IEnumerable<string> urlList)
{
    var returnList = new Dictionary<string, byte[]>();
    using (var client = new WebClient())
    {
        foreach (var url in urlList)
        {
            client.DownloadDataCompleted += (sender1, e1) => returnList.Add(GetFileNameFromUrlString(url), e1.Result);
            client.DownloadDataAsync(new Uri(url));
        }
    }
    return returnList;
}

private static string GetFileNameFromUrlString(string url)
{
    var uri = new Uri(url);
    return System.IO.Path.GetFileName(uri.LocalPath);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  • First, you tagged your question with async-await without actually using it. There really is no reason anymore to use the old asynchronous paradigms.
  • To wait asynchronously for all concurrent async operation to complete you should use Task.WhenAll which means that you need to keep all the tasks in some construct (i.e. dictionary) before actually extracting their results.
  • At the end, when you have all the results in hand you just create the new result dictionary by parsing the uri into the file name, and extracting the result out of the async tasks.

async Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls)
{
    var dictionary = urls.ToDictionary(
        url => new Uri(url),
        url => new WebClient().DownloadDataTaskAsync(url));

    await Task.WhenAll(dictionary.Values);

    return dictionary.ToDictionary(
        pair => Path.GetFileName(pair.Key.LocalPath),
        pair => pair.Value.Result);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...