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

时间:2011-11-24 14:12:44

标签: c# nested-loops parallel-processing

Following to this post,我希望并行化这种方法:

    public IEnumerable<string> GetAllLogs(IEnumerable<IComputer> 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:“I”,“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秒内运行。 Thread.Sleep(1000)方法中有GetLogs

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

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

并在几秒钟后运行。

我希望方法返回一个IEnumerable

1 个答案:

答案 0 :(得分:16)

这就是你需要的:

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

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

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

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

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