如何制作IEnumerable方法的并行方法

在这篇文章之后 ,我想要并行化这个方法:

public IEnumerable GetAllLogs(IEnumerable computers) { foreach (var cpt in computers) { foreach (var log in cpt.GetLogs()) { yield return log; } } } 

当其中一个方法GetLogs完成时,我希望方法“yield returns”成为日志。 如果我有4台计算机返回:

  • 计算机01:“a”,“b”,“c”,“d”,“e”
  • 计算机02:“1”,“2”,“3”,“4”,“5”
  • 计算机03:“alpha”,“beta”,“gamma”,“delta”,“epsilon”
  • 计算机04:“我”,“II”,“III”,“IV”,“V”

使用“顺序方法”,输出为:

 a b c d e 1 2 3 4 5 alpha beta gamma delta epsilon I II III IV V 

这些方法在20秒内运行。 GetLogs方法中有一个Thread.Sleep(1000)

我希望输出看起来像这样:

 III a 4 gamma b c IV 5 d II beta e 1 2 delta alpha 3 epsilon I 

并在几秒钟内运行。

我希望方法返回一个IEnumerable

这就是你需要的:

 public IEnumerable GetAllLogsParallel(IEnumerable computers) { return computers .AsParallel() .SelectMany(cpt => cpt.GetLogs()); } 

如果你想同时开始处理4 computer ,你可以像这样调整并行度:

 public IEnumerable GetAllLogsParallel(IEnumerable computers) { return computers .AsParallel() .WithDegreeOfParallelism(4) .SelectMany(cpt => cpt.GetLogs()); } 

以下是仅供理解的简化说明。 要了解更多信息,请访问MSDN上的PLINQ(Parallel LINQ) 。

好吧, .AsParallel() – 将可枚举的computers分成4个部分,同时启动4个线程。 每个线程为每台computer执行cpt.GetLogs() 。 结果是IEnumerable> – 可枚举的枚举数。 SelectMany()用于通过连接内部枚举和消除外部枚举来展平此列表。 结果按照到达顺序自动合并回主线程。