我正在将大量文件从一台服务器复制到其他几台服务器。
我有一个包含订单的复制操作列表,因此服务器a的文件在列表中排在第一位,服务器b的文件位于列表的末尾。
我在列表中使用AsParallel.AsOrdered()以确保首先将文件复制到第一个服务器,然后才将线程释放到第二个服务器。
它似乎没有工作,因为它会同时将文件复制到两个服务器,我错过了什么,是否有更好的方法来编写此代码。我检查了大文件,以确实看到订单,似乎没有重新选择列表顺序
var dotheCopy = copy.ToArray().OrderBy(a => a.GroupId);
var copyList = new List<CopyOps>();
foreach (var x in dotheCopy)
{
... some validation code
copyList.Add(x);
}
copyList.AsParallel().AsOrdered().WithDegreeOfParallelism(5)
.ForAll(x => this.DoTheCopy(x));
答案 0 :(得分:4)
AsOrdered
不保证执行顺序。它保证结果将被订购。
Enumerable.Range(0, 3).AsParallel().Select(x => x); // 3,1,2,
Enumerable.Range(0, 3).AsParallel().AsOrdered().Select(x => x); // 1,2,3
由于ForAll
没有返回任何内容,因此将其与AsOrdered
相结合是没用的。
看起来你的实际目标是按顺序处理你的物品,但是5批次,对吗?换句话说,你需要节流。如果是这样,您可以使用TPL Dataflow中的ActionBlock<T>
var block = new ActionBlock<CopyOps>(DoTheCopy,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 5
});
var tasks = copyList.Select(item => block.SendAsync(item));
await Task.WhenAll(tasks);
或者,更简单的方法,如果阻止主线程不是问题
Parallel.ForEach(copyList,
new ParallelOptions { MaxDegreeOfParallelism = 5 },
DoTheCopy);
答案 1 :(得分:2)