同时下载多个文件,并在所有文件完成后继续下载



我们正在编写一个小工具,该工具从我们的Web服务器下载文件并分析它们。这是很多文件,大约需要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(),那么它将像以前一样留下。

我考虑使用继续使用 - 但是该块内部该怎么办?它怎么知道所有其他文件都完成下载?

我什至考虑过将任务存储在集合中,并且在foreach循环的末尾编写了另一个循环,并在其上调用等待方法。

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

您可以将所有任务存储在集合中,然后致电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

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

除非您真的需要/想要将所有下载的文件限制到一个大字符串中(并写入逻辑以稍后检索个体文件),我取而代之的是将字符串存储在线程安全列表中(sush as System.Collections.Collections.concurrent.concurrent.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);
});

最新更新