2013-05-13 36 views
11

Tôi đang cố gắng tải xuống nhiều tệp từ internet và chờ tất cả các tệp đó hoàn tất. Đây là một ứng dụng giao diện điều khiển C# mà tôi đang chạy, vì vậy không cần xử lý sự kiện thanh tiến trình nào cần thiết. Tuy nhiên nó hiện chỉ tiếp tục thực thi mã mặc dù tất cả các tệp chưa được tải xuống.Tải xuống nhiều tệp không đồng bộ và đợi cho tất cả các tệp hoàn tất trước khi thực hiện phần còn lại của mã

  • 1.Tải xuống tất cả các tệp!
  • 2.Finished Tải xuống tệp A
  • 3.Finished Tải xuống tất cả các tệp!
  • 4.Finished Tải File B
  • 5.Finished Tải file C

Làm thế nào bạn sẽ chờ đợi cho đến khi tất cả các file async tải xong.

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

Trả lời

32

Các thành viên DownloadFileAsync/DownloadFileCompleted của WebClient sử dụng Event-based Asynchronous Pattern. Nếu bạn muốn sử dụng asyncawait, bạn nên sử dụng Task-based Asynchronous Pattern.

Trong trường hợp này, bạn nên sử dụng DownloadFileTaskAsync member, như vậy:

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

Xin lưu ý rằng Context.listOfLocalDirectories.AddErrors.printError bạn phương pháp này cần được threadsafe.

+0

Cảm ơn bạn đã đứng đầu. Đảm bảo localDirectories của tôi là thread an toàn cũng đã thêm trình xử lý sự kiện hoàn thành của riêng tôi. Cảm ơn bạn vì tất cả sự giúp đỡ. Điều này cũng giúp tôi hiểu được các vấn đề với các tác vụ không đồng bộ khác của tôi. – user2100493

+0

Tính năng này khả dụng kể từ 4.5 – Natxo

+0

Có ngoại lệ không tải xuống được tệp nếu URL cố gắng tải xuống không trả về 404 Không tìm thấy? –