Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 同时下载多个文件,并在所有文件下载完成后继续_C#_.net_Task Parallel Library - Fatal编程技术网

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

C# 同时下载多个文件,并在所有文件下载完成后继续,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,我们正在编写一个从web服务器下载文件并进行分析的小工具。它有很多文件,下载大约需要10分钟,我们希望通过允许应用程序并行下载文件来缩短下载时间 目前,我们有一个循环遍历要下载的文件列表,只需下载它们并将文件名添加到分隔字符串中: foreach (var File in ServerFiles) { string sFileName = File.Uri.LocalPath.ToString(); // some internal logic and initializatio

我们正在编写一个从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(),那么它将像以前一样离开它

我考虑过使用continueWith,但是在这个块中应该做什么呢?它如何知道所有其他文件都已下载完毕

我甚至想过将任务存储在一个集合中,并在foreach循环结束时编写另一个循环,该循环接受所有任务并对其调用wait方法


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

您可以将所有任务存储在一个集合中,然后调用 Task.WaitAll(你的数组); 您的代码将被阻止,直到所有任务完成。 大概是这样的:

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
var tasks=newlist();
foreach(ServerFiles中的var文件)
{
字符串sFileName=File.Uri.LocalPath.ToString();
//一些内部逻辑和初始化
Task downloadTask=oBlob.DownloadToStreamAsync(fileStream);
任务。添加(下载任务);
sFiles+=sFileName.Replace(“/”+容器+“/”,“)+”,“;
}
Task.WaitAll(任务);
//继续这里

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

除非您确实需要/希望将所有下载的文件压缩成一个大字符串(并写入逻辑以稍后检索单个文件),否则我会将字符串存储在线程安全列表中(sush作为System.Collections.Concurrent.ConcurrentBag,它允许多个线程写入该列表)

ConcurrentBag downloadedFiles=new ConcurrentBag();
Parallel.ForEach(ServerFiles,file=>
{
字符串sFileName=file.Uri.LocalPath.ToString();
//一些内部逻辑和初始化
oBlob.DownloadToStream(fileStream);
downloaddedfiles.Add(sFileName);
});

您确定并行下载会更快吗?你发现瓶颈了吗?源磁盘、网络、目标磁盘?并行性是如何改善瓶颈的?如果所有文件确实都在同一台服务器上,您还需要增加。
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);
});