简体   繁体   English

WebClient.DownloadFileAsync - 一次下载一个文件

[英]WebClient.DownloadFileAsync - Download files one at a time

I am using the code below to download multiple attachments from a TFS server: 我使用下面的代码从TFS服务器下载多个附件:

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

I would like to download multiple files using DownloadFileAsync, but I want them to be downloaded one by one. 我想使用DownloadFileAsync下载多个文件,但我希望逐个下载它们。

One may ask "Why don't you just use the synchronous DownloadFile method?" 有人可能会问“你为什么不使用同步的DownloadFile方法?” Its because: 这是因为:

  1. I want to make use of the events provided by DownloadFileAsync. 我想利用DownloadFileAsync提供的事件。
  2. I don't want to make multiple instances of the Webclient to avoid flooding the server. 我不想创建Webclient的多个实例以避免泛滥服务器。

This is the solution that I thought of: 这是我想到的解决方案:

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

However, there are a couple of problems with this approach: 但是,这种方法存在一些问题:

  1. The Thread.Sleep() is locking up my Form. Thread.Sleep()正在锁定我的表单。 I still need to make my own Thread or use BackgroundWorker. 我仍然需要创建自己的Thread或使用BackgroundWorker。 (I would like to avoid this as much as possible) (我想尽可能避免这种情况)
  2. The DownloadFileCompleted event is being triggered after ALL files has been downloaded. 下载所有文件后,将触发DownloadFileCompleted事件。 I don't know if this is a side-effect of using System.Threading.Thread.Sleep(1000); 我不知道这是否是使用System.Threading.Thread.Sleep(1000)的副作用;

Is there a better approach to download files one at a time using WebClient.DownloadFileAsync? 有没有更好的方法使用WebClient.DownloadFileAsync一次下载一个文件?

Thanks! 谢谢!

To simplify the task you can create separated attachment list: 要简化任务,您可以创建单独的附件列表:

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

where list is private field with type List<Attachment> . 其中list是私有字段,类型为List <Attachment> After this you should configure WebClient and start downloading of first file: 在此之后,您应该配置WebClient并开始下载第一个文件:

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

Your DownloadFileComplete handler should check if not all files already downloaded and call DownloadFileAsync again: 您的DownloadFileComplete处理程序应检查是否已下载所有文件并再次调用DownloadFileAsync:

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

This code is not optimized solution. 此代码不是优化解决方案。 This is just idea. 这只是想法。

At the risk of sounding like an idiot, this worked for me: 冒着听起来像白痴的风险,这对我有用:

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

Where client is an instance of a WebClient object. 其中clientWebClient对象的实例。

我认为应该使用Queue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM