使用DownloadDataAsync下载AWAIT多个文件

Wes*_*ley -3 .net c# webclient async-await webclient-download

我有一个zip文件创建者,它接收一个String[]Urls,并返回一个包含所有文件的zip文件String[]

我想会有很多这方面的例子,但我似乎找不到"如何异步下载多个文件并在完成后返回"的答案

如何一次下载{n}个文件,仅在所有下载完成后返回词典?

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);
}
Run Code Online (Sandbox Code Playgroud)

i3a*_*non 5

  • 首先,您在async-await没有实际使用的情况下标记了您的问题.没有理由再使用旧的异步范例了.
  • 异步等待所有并发async操作完成,您应该使用Task.WhenAll这意味着您需要在实际提取结果之前将所有任务保留在某些构造(即字典)中.
  • 最后,当您掌握了所有结果时,您只需通过解析uri文件名并从async任务中提取结果来创建新的结果字典.

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);
}
Run Code Online (Sandbox Code Playgroud)