【问题标题】:Downloading multiple files at the same time and continue after all files finished downloading同时下载多个文件并在所有文件下载完成后继续
【发布时间】:2014-01-28 08:06:48
【问题描述】:

我们正在编写一个小工具,用于从我们的网络服务器下载文件并对其进行分析。文件很多,下载大约需要 10 分钟,我们希望通过允许应用并行下载文件来缩短下载时间。

目前我们有一个循环遍历要下载的文件列表,只需下载它们并将文件名添加到分隔字符串中:

foreach (var File in ServerFiles)
{
    string sFileName = File.Uri.LocalPath.ToString();
    // some internal logic and initialization 
    oBlob.DownloadToStream(fileStream);
    sFiles += sFileName.Replace("/" + Container + "/", "") + ",";
}

我们已将其更改为:

foreach (var File in ServerFiles)
{
    string sFileName = File.Uri.LocalPath.ToString();
    // some internal logic and initialization 
    Task downloadTask = oBlob.DownloadToStreamAsync(fileStream);
    sFiles += sFileName.Replace("/" + Container + "/", "") + ",";
}

现在我的问题是如何处理我返回的任务。如果我只是调用 downloadTask.wait() 那么它会像以前一样离开它。

我考虑过使用 continueWith - 但是在该块内应该做什么?它如何知道所有其他文件都已完成下载?

我什至考虑将任务存储在一个集合中,并在 foreach 循环结束时编写另一个循环来接收所有任务并调用它们的 wait 方法。

解决此类问题的正确方法是什么?

【问题讨论】:

  • 您确定并行下载它们会更快吗?你发现瓶颈了吗?源磁盘、网络、目标磁盘?并行性如何改善瓶颈?
  • 如果所有文件确实在同一台服务器上,还需要增加ServicePointManager.DefaultConnectionLimit

标签: c# .net task-parallel-library


【解决方案1】:

您可以将所有任务存储在一个集合中,然后调用 Task.WaitAll(yourArray); 在所有任务完成之前,您的代码将被阻止。 像这样的:

var tasks=new List<Task>();
foreach (var File in ServerFiles)
{
    string sFileName = File.Uri.LocalPath.ToString();
    // some internal logic and initialization 
    Task downloadTask = oBlob.DownloadToStreamAsync(fileStream);
tasks.Add(downloadTask);
    sFiles += sFileName.Replace("/" + Container + "/", "") + ",";
}
Task.WaitAll(tasks);
//Continue here

【讨论】:

    【解决方案2】:

    我会使用Parallel.Foreach 使用单独的线程下载所有文件。

    除非您真的需要/想要将所有下载的文件合并为一个大字符串(并编写逻辑以稍后检索单个文件),否则我将字符串存储在线程安全列表中(sush 作为 System.Collections.Concurrent .ConcurrentBag 允许多个线程写入列表)。

    ConcurrentBag<string> downloadedFiles = new ConcurrentBag<string>();
    
    Parallel.ForEach(ServerFiles, file =>
    {
        string sFileName = file.Uri.LocalPath.ToString();
        // some internal logic and initialization 
        oBlob.DownloadToStream(fileStream);
        downloadedFiles.Add(sFileName);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-25
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 2012-04-30
      • 2021-12-03
      相关资源
      最近更新 更多