如何同时下载正确的文件?

Lea*_*ner 1 c# asynchronous task-parallel-library async-await parallel.foreach

我正在尝试同时下载多个文件。但是所有文件都在逐一下载。所以,首先下载这个文件@"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",然后开始下载这个文件@"http://download.geofabrik.de/europe/finland-latest.osm.pbf",,下一个要下载的文件是@"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf"等等。

但是我想同时下载。

因此,我根据此答案中的代码编写了以下代码:

static void Main(string[] args)
{
    Task.Run(async () =>
    {
        await DownloadFiles();
    }).GetAwaiter().GetResult();
}

public static async Task DownloadFiles()
{
    IList<string> urls = new List<string>
    {
        @"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
    };

    foreach (var url in urls)
    {
        string fileName = url.Substring(url.LastIndexOf('/'));
        await DownloadFile(url, fileName);
    }            
}

public static async Task DownloadFile(string url, string fileName)
{
    string address = @"D:\Downloads";
    using (var client = new WebClient())
    {
        await client.DownloadFileTaskAsync(url, $"{address}{fileName}");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我在我的文件系统中看到时,我看到文件正在逐个下载而不是同时下载:

在此处输入图片说明

此外,我尝试使用这种方法,但是没有同时下载:

static void Main(string[] args)
{
    IList<string> urls = new List<string>
    {
        @"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
    };

    Parallel.ForEach(urls,
        new ParallelOptions { MaxDegreeOfParallelism = 10 },
        DownloadFile);
}

public static void DownloadFile(string url)
{
    string address = @"D:\Downloads";
    using (var sr = new StreamReader(WebRequest.Create(url)
           .GetResponse().GetResponseStream()))
    using (var sw = new StreamWriter(address + url.Substring(url.LastIndexOf('/'))))
    {
        sw.Write(sr.ReadToEnd());
    }
}
Run Code Online (Sandbox Code Playgroud)

你能告诉我如何同时下载吗?

任何帮助将不胜感激。

Eld*_*dar 5

    foreach (var url in urls)
    {
        string fileName = url.Substring(url.LastIndexOf('/'));
        await DownloadFile(url, fileName); // you wait to download the item and then move the next
    }   
Run Code Online (Sandbox Code Playgroud)

相反,您应该创建任务并等待所有任务完成。

public static Task DownloadFiles()
{
    IList<string> urls = new List<string>
    {
        @"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
        @"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
    };

       var tasks = urls.Select(url=> {
           var fileName = url.Substring(url.LastIndexOf('/'));
             return DownloadFile(url, fileName);    
         }).ToArray();   
         return Task.WhenAll(tasks);       
}
Run Code Online (Sandbox Code Playgroud)

其余代码可以保持不变。