下载多个文件异步并等待它们全部完成,然后执行代码的其余部分

问题描述:

我试图从互联网上下载多个文件并等待所有文件完成。这是我正在运行的C#控制台应用程序,因此不需要进度条事件处理程序。但是,即使所有文件都没有被下载,它目前只是继续执行代码。下载多个文件异步并等待它们全部完成,然后执行代码的其余部分

  • 1.下载所有文件!
  • 2.Finished下载文件A
  • 3.Finished下载所有文件!
  • 4.Finished下载文件B
  • 5.Finished下载文件C

你会如何等待,直到所有异步下载文件完成。

private void DownloadMultipleFiles(List<DocumentObject> doclist) 
    { 
     foreach(var value in doclist){ 
      try 
      { 
       using (WebClient webClient = new WebClient()) 
       { 
        string downloadToDirectory = @Resources.defaultDirectory + value.docName; 
        webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; 
        webClient.DownloadFileCompleted += client_DownloadFileCompleted; 
        webClient.DownloadFileAsync(new Uri(value.docUrl), @downloadToDirectory); 

        //Add them to the local 
        Context.listOfLocalDirectories.Add(downloadToDirectory); 
       }   
      } 
      catch (Exception) 
      { 
       Errors.printError("Failed to download File: " + value.docName); 
      } 
     } 
    } 

WebClientDownloadFileAsync/DownloadFileCompleted成员使用Event-based Asynchronous Pattern。如果你想使用asyncawait,你应该使用Task-based Asynchronous Pattern

在这种情况下,你应该使用DownloadFileTaskAsync member,因为这样的:

private async Task DownloadFileAsync(DocumentObject doc) 
{ 
    try 
    { 
    using (WebClient webClient = new WebClient()) 
    { 
     string downloadToDirectory = @Resources.defaultDirectory + doc.docName; 
     webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; 
     await webClient.DownloadFileTaskAsync(new Uri(doc.docUrl), @downloadToDirectory); 

     //Add them to the local 
     Context.listOfLocalDirectories.Add(downloadToDirectory); 
    }   
    } 
    catch (Exception) 
    { 
    Errors.printError("Failed to download File: " + doc.docName); 
    } 
} 

private async Task DownloadMultipleFilesAsync(List<DocumentObject> doclist) 
{ 
    await Task.WhenAll(doclist.Select(doc => DownloadFileAsync(doc))); 
} 

请注意,您的Context.listOfLocalDirectories.AddErrors.printError方法应该是线程安全的。

+0

谢谢你的抬头。确保我的localDirectories是线程安全的,并添加了我自己的完成事件处理程序。感谢您的帮助。这也有助于我理解我的其他异步任务的问题。 – user2100493 2013-05-13 04:04:39

+0

这是可用的4.5 – Natxo 2016-09-13 15:10:00

+0

如果试图从网站下载的URL返回404 Not Found? – 2017-12-16 20:35:47