并行化IO绑定(网络)ForEach循环

时间:2014-01-21 22:37:16

标签: c# amazon-web-services parallel-processing task-parallel-library parallel.foreach

根据选择的选项,我有几种不同的方式可以将整个目录上传到我的应用程序中的Amazon S3。目前,其中一个选项将并行执行多个目录的上载。我不确定这是不是一个好主意,因为在某些情况下它会加快上传速度,而其他情况则会减慢它的速度。加速似乎是在有一堆小目录时,但如果批处理中有大型目录,则速度会变慢。我正在使用下面看到的并行ForEach循环并使用AWS API的TransferUtility.UploadDirectoryAsync()方法:

Parallel.ForEach(dirs,myParallelOptions, 
                   async dir => { await MyUploadMethodAsync(dir) };

TransferUtility.UploadDirectoryAsync()方法在MyUploadMethodAsync()范围内。 TransferUtility的上传方法都执行单个文件的部分并行上传(如果大小足够大),所以执行目录的并行上传可能是过度的。显然,我们仍然限制可用带宽的数量,因此这可能是浪费,我应该只使用UploadDirectoryAsync()方法的常规foreach循环。任何人都可以提供一些有关并行化的坏情况的见解吗?

1 个答案:

答案 0 :(得分:5)

你真的测试过吗?您使用它的方式Parallel.ForEach可能会在任何MyUploadMethodAsync完成之前返回,因为async lambda:

Parallel.ForEach(dirs,myParallelOptions, 
    async dir => { await MyUploadMethodAsync(dir) };

Parallel.ForEach适用于CPU绑定任务。对于IO绑定任务,您可能正在寻找类似的东西:

var tasks = dirs.Select(dir => MyUploadMethodAsync(dir));
await Task.WhenAll(tasks);
// or Task.WaitAll(tasks) if you need a blocking wait