Как сделать метод IEnumerable параллельным - PullRequest
9 голосов
/ 24 ноября 2011

Следуя этому посту , я хочу распараллелить этот метод:

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

Я хочу, чтобы метод "yield возвращает" журнал, когда один из методов GetLogs завершен. Если у меня есть 4 компьютера, который возвращает:

  • Компьютер 01: «a», «b», «c», «d», «e»
  • Компьютер 02: «1», «2», «3», «4», «5»
  • Компьютер 03: «альфа», «бета», «гамма», «дельта», «эпсилон»
  • Компьютер 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

1 Ответ

16 голосов
/ 24 ноября 2011

Это то, что вам нужно:

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

Если вы хотите начать обработку 4 computer -ов одновременно, вы можете настроить степень параллелизма следующим образом:

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

Ниже приведено упрощенное объяснение только для понимания.Чтобы узнать больше об этом, просто посетите PLINQ (Parallel LINQ) на MSDN.

Ну, .AsParallel() - разбивает перечислимое число computers на 4 части и запускает 4 потока одновременно.Каждый поток выполняет cpt.GetLogs() для каждого computer.Результат - IEnumerable<IEnumerable<string>> - перечислимые перечислимые.SelectMany() используется, чтобы сгладить этот список путем объединения внутренних перечислимых значений и исключения внешних.Результаты автоматически объединяются в основной поток в порядке их поступления.

...