Что эквивалентно Spliterator в C #? - PullRequest
0 голосов
/ 26 августа 2018

В Java я могу написать реализацию интерфейса Spliterator, в которой я могу указать, как именно исходная коллекция будет разделена на подколлекции для параллельной обработки.

Но я не понимаю, как это сделать в C #, все, что я знаю, это то, что вы можете позвонить AsParallel на IEnumerable, но вы можете контролировать процесс разделения?

Например, моя исходная коллекция представляет собой массив, и я хочу разбить его на 5 подмассивов элементов и хочу, чтобы linq работал с этими подмассивами. Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

В настоящее время C # доза не предлагает такую ​​функцию, как Java. Параллельные задачи в C # имеют параметр MaxDegreeOfParallelism , который позволяет указать максимальное количество одновременных задач, включенных экземпляром ParallelOptions, и автоматически обрабатывает количество задач.

0 голосов
/ 26 августа 2018

Если у вас есть особые требования к разделению, вам следует взглянуть на Пользовательские разделители для PLINQ и TPL и Как: реализовать разделитель для статического разбиения .Они приводят пример того, как вы можете реализовать Partitioner<TSource>, который предположительно похож на Java Spliterator.

Однако, в большинстве случаев более полезно позволить инфраструктуревыбрать свою собственную стратегию динамического разделения.Если вы хотите ограничить уровень параллелизма до 5, вы можете использовать WithDegreeOfParallelism:

var summary = ints
    .AsParallel()
    .WithDegreeOfParallelism(5)
    .Aggregate(
        seed: (
            count: 0,
            sum: 0,
            min: int.MaxValue,
            max: int.MinValue),
        updateAccumulatorFunc: (acc, x) => (
            count: acc.count + 1,
            sum: acc.sum + x,
            min: Math.Min(acc.min, x),
            max: Math.Max(acc.max, x)),
        combineAccumulatorsFunc: (acc1, acc2) => (
            count: acc1.count + acc2.count,
            sum: acc1.sum + acc2.sum,
            min: Math.Min(acc1.min, acc2.min),
            max: Math.Max(acc1.max, acc2.max)),
        resultSelector: acc => (
            acc.count,
            acc.sum,
            acc.min,
            acc.max,
            avg: (double)acc.sum / acc.count));
...