2010-01-11 32 views
6

Tôi đang sử dụng mã dưới đây để tải nhiều file đính kèm từ một máy chủ TFS:WebClient.DownloadFileAsync - Tải file cùng một lúc

foreach (Attachment a in wi.Attachments) 
{  
    WebClient wc = new WebClient(); 
    wc.Credentials = (ICredentials)netCred; 
    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); 
    wc.DownloadFileAsync(a.Uri, "C:\\" + a.Name); 
} 

Tôi muốn tải nhiều dữ liệu sử dụng DownloadFileAsync, nhưng tôi muốn họ được tải xuống từng cái một.

Người ta có thể hỏi "Tại sao bạn không sử dụng phương thức DownloadFile đồng bộ?" Bởi vì:

  1. Tôi muốn sử dụng các sự kiện được cung cấp bởi DownloadFileAsync.
  2. Tôi không muốn tạo nhiều phiên bản của Webclient để tránh làm ngập máy chủ.

Đây là giải pháp mà tôi nghĩ đến:

foreach (Attachment a in wi.Attachments) 
{   
    WebClient wc = new WebClient(); 
    wc.Credentials = (ICredentials)netCred; 
    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); 
    wc.DownloadFileAsync(a.Uri, "C:\\" + a.Name); 
    while (wc.IsBusy) 
    { 
     System.Threading.Thread.Sleep(1000); 
    } 
} 

Tuy nhiên, có một vài vấn đề với cách tiếp cận này:

  1. Các Thread.Sleep() được khóa lên của tôi Hình thức. Tôi vẫn cần tạo chủ đề của riêng mình hoặc sử dụng BackgroundWorker. (Tôi muốn tránh điều này càng nhiều càng tốt)
  2. Sự kiện DownloadFileCompleted đang được kích hoạt sau khi TẤT CẢ tệp đã được tải xuống. Tôi không biết nếu đây là một tác dụng phụ của việc sử dụng System.Threading.Thread.Sleep (1000);

Có cách nào tốt hơn để tải xuống từng tệp một lúc bằng WebClient.DownloadFileAsync không?

Cảm ơn!

+2

btw, bạn có thể sử dụng 'System.IO.Path.Combinte (" C: ", a.Name"); ' – abatishchev

+0

Tôi đang cố gắng nhưng một số câu trả lời chỉ đơn giản là không thể chấp nhận được. – Ian

+0

Bạn có thể khắc phục sự cố chặn luồng bằng cách thực hiện việc này: 'while (wc.IsBusy) {}'. Bằng cách này, miễn là 'wc.IsBusy' là' true', việc thực hiện sẽ bị "kẹt" trong dấu ngoặc đơn "không làm gì cả". –

Trả lời

8

Để đơn giản hóa các nhiệm vụ bạn có thể tạo danh sách tập tin đính kèm riêng biệt:

list = new List<Attachment>(wi.Attachments); 

nơi danh sách là lĩnh vực riêng với loại Danh sách < đính kèm >. Sau này, bạn nên cấu hình WebClient và bắt đầu tải về tập tin đầu tiên:

if (list.Count > 0) { 
    WebClient wc = new WebClient(); 
    wc.Credentials = (ICredentials)netCred; 
    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); 
    wc.DownloadFileAsync(list[0].Uri, @"C:\" + list[0].Name); 
} 

handler DownloadFileComplete bạn nên kiểm tra nếu không phải tất cả các file đã tải về và gọi DownloadFileAsync một lần nữa:

void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { 
    // ... do something useful 
    list.RemoveAt(0); 
    if (list.Count > 0) 
     wc.DownloadFileAsync(list[0].Uri, @"C:\" + list[0].Name); 
} 

Mã này không được tối ưu hóa giải pháp . Đây chỉ là ý tưởng.

0

Tôi nghĩ rằng nên sử dụng Queue

+0

Tôi thực sự đồng ý RE sử dụng Hàng đợi, nhưng như Harshal nói bạn nên giải thích thêm những gì bạn đang nói. –

1

Lúc nguy cơ sounding như một thằng ngốc, điều này đã làm việc cho tôi:

Console.WriteLine("Downloading..."); 
client.DownloadFileAsync(new Uri(file.Value), filePath); 
while (client.IsBusy) 
{ 
    // run some stuff like checking download progress etc 
} 
Console.WriteLine("Done. {0}", filePath); 

đâu client là một thể hiện của một đối tượng WebClient.

+0

Hoạt động khá tốt (Y) –

Các vấn đề liên quan