Последовательная итерация (Parallel.For())

Вывод этого кода каждый раз разный. Можно ли иметь последовательный вывод i (количество итераций) от 0 до 21?

  static void Main(string[] args)
    {

        int N = 1000;
            Parallel.For(0, N, (i, loop) =>
            {
                Console.WriteLine(i);
                if (i == 21)
                {
                    loop.Break();
                }
            });
            Console.ReadLine();
    }

person Giliweed    schedule 10.07.2014    source источник
comment
Да, это возможно - не используйте параллель. Вам нужно либо параллельное выполнение с неопределенным порядком, либо последовательное - с определенным.   -  person zerkms    schedule 10.07.2014
comment
Но если не использовать параллель, то это будет простой цикл For().   -  person Giliweed    schedule 10.07.2014
comment
Parallel будет создавать поток для каждой итерации, и вы не сможете обеспечить последовательность выполнения потоков.   -  person Adil    schedule 10.07.2014
comment
Если я хочу выполнить первые (0-5) пять итераций, затем последние (17-21) пять итераций, а затем оставшиеся итерации, как мне это сделать? последовательный вывод 0,1,2,3,4,5,17,18,19,20,21,.... остаток.   -  person Giliweed    schedule 10.07.2014
comment
Но если не использовать параллель, то это будет простой цикл For() --- точно. Это то, что ты хочешь.   -  person zerkms    schedule 10.07.2014


Ответы (2)


Вместо этого используйте цикл foreach:

foreach (var VARIABLE in (Enumerable.Range(0, 10).AsParallel().AsOrdered()))
{
    Console.WriteLine(VARIABLE);
}

Пример с индексом

foreach (var obj in Enumerable.Range(0, 10)
    .Select((s, i) => new {index = i, value = s})
    .AsParallel()
    .Select(obj => new {obj.index, value = obj.value*obj.value, thread=Thread.CurrentThread.ManagedThreadId})
    .OrderBy(o => o.index))
{
    Console.WriteLine("{0}:{1} on {2}", obj.index, obj.value, obj.thread);
}

Результаты от Core i7.

0:0 on 1
1:1 on 3
2:4 on 5
3:9 on 1
4:16 on 1
5:25 on 1
6:36 on 1
7:49 on 1
8:64 on 1
9:81 on 1
person Darek    schedule 10.07.2014
comment
один вопрос: если я выполняю одни и те же операции на каждой итерации и добавляю результаты в массив, будет ли возвращаемое значение каждой итерации также упорядочено внутри массива? - person Giliweed; 10.07.2014
comment
Я бы порекомендовал вам добавить индекс упорядочения, выполнять его параллельно, а не упорядочивать по этому индексу. Он будет выполняться быстрее. - person Darek; 10.07.2014
comment
Звучит как раз то, что мне нужно. Можете ли вы помочь мне с примером кода? или ссылка может помочь создать этот код. - person Giliweed; 10.07.2014
comment
Значение потока одинаково на каждой итерации. Вы запускаете каждую итерацию в одном потоке каждый раз? --- - person Giliweed; 10.07.2014
comment
Возможно, у вашего ПК меньше ресурсов, чем у меня... Мой показал 3-4 разных идентификатора потока. Попробуйте увеличить количество элементов или увеличить время обработки каждого элемента. - person Darek; 10.07.2014
comment
Да. Увеличение диапазона до 100 показывает 2 разных идентификатора потока. ---Спасибо. - person Giliweed; 10.07.2014
comment
Исправлена ​​незначительная ошибка. Должно быть .Select((value,selector)-›...) ака. (значение, индекс). - person Darek; 10.07.2014

При использовании метода Parallel.For определенный порядок выполнения не гарантируется. Преимущество заключается в том, что цикл выполняется быстрее на компьютере с доступными ядрами, поскольку шаги часто выполняются одновременно и параллельно. У вас по-прежнему есть гарантия, что все итерации цикла будут выполнены к моменту завершения цикла, но не в том порядке, в котором они будут выполняться. Если вы хотите запустить последовательный цикл, вам следует использовать for.

person etr    schedule 10.07.2014
comment
Спасибо. Теперь мне ясно, что у меня нет другого выбора, кроме как использовать For() - person Giliweed; 10.07.2014