Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
709 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 Reply

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);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...