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

标签 c# asp.net multithreading webclient download

我正在使用下面的代码从 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);
}

我想使用 DownloadFileAsync 下载多个文件,但我希望一个一个地下载它们。

有人可能会问“为什么不直接使用同步 DownloadFile 方法呢?”这是因为:

  1. 我想利用 DownloadFileAsync 提供的事件。
  2. 我不想制作 Webclient 的多个实例以避免服务器泛滥。

这是我想到的解决方案:

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

但是,这种方法有几个问题:

  1. Thread.Sleep() 正在锁定我的表单。我仍然需要创建自己的线程或使用 BackgroundWorker。 (我想尽可能避免这种情况)
  2. 下载所有 文件后触发DownloadFileCompleted 事件。我不知道这是否是使用 System.Threading.Thread.Sleep(1000); 的副作用

是否有使用 WebClient.DownloadFileAsync 一次下载一个文件的更好方法?

谢谢!

最佳答案

为了简化任务,您可以创建单独的附件列表:

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

其中 list 是类型为 List 的私有(private)字段。 在此之后,您应该配置 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);
}

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

此代码不是优化的解决方案。这只是想法。

关于c# - WebClient.DownloadFileAsync - 一次下载一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2042258/

相关文章:

c# - 当 Windows Shell 替换为 Windows Forms 应用程序时,第一次按键丢失

c# - 如何从后面的代码访问数据模板中的控件?

javascript - ASPX - 如何从 Txt 文件读取行然后将文本存储在字符串中

java - 静态方法和静态 block 之间的线程安全

java - computeIfAbsent 如何随机使 ConcurrentHashMap 失败?

c# - 检测在 C# 中使用 openas_rundll 打开的选定程序

c# - 动态按钮表

c# - 在没有存储过程的情况下从 SQL Server 表生成 C# 类

asp.net - IIS 和静态内容?

multithreading - 在多线程(使用克隆)程序中调试段错误