body, при условии, что используется приведенная ниже форма метода For Each ().

public static ParallelLoopResult

ForEach<TSource>(IEnumerable<TSource> source,

ActiorKTSource, ParallelLoopState> body)

В приведенном ниже примере программы демонстрируется применение метода For Each () на практике. Как и прежде, в данном примере создается крупный массив целых значений. А отличается данный пример от предыдущих тем, что метод, выполняющийся на каждом шаге цикла, просто выводит на консоль значения из массива. Как правило, метод WriteLine () в распараллеливаемом цикле не применяется, потому что ввод- вывод на консоль осуществляется настолько медленно, что цикл оказывается полностью привязанным к вводу-выводу. Но в данном примере метод WriteLine () применяется исключительно в целях демонстрации возможностей метода ForEach (). При обнаружении отрицательного значения выполнение цикла прерывается вызовом метода Break (). Несмотря на то что метод Break () вызывается в одной задаче, другая задача может по-прежнему выполняться в течение нескольких шагов цикла, прежде чем он будет прерван, хотя это зависит от конкретных условий работы среды выполнения.

// Использовать объекты типа ParallelLoopResult и ParallelLoopState, а также // метод Break () вместе с методом ForEachO для параллельного выполнения цикла.

using System;

using System.Threading.Tasks;

class DemoParallelForWithLoopResult { static int[] data;

// Метод, служащий в качестве тела параллельно выполняемого цикла.

// В данном примере переменной v передается значение элемента массива // данных, а не индекс этого элемента.

static void DisplayData(int v, ParallelLoopState pis) {

// Прервать цикл при обнаружении отрицательного значения, if (v < 0) pls.Break ();

Console.WriteLine('Значение: ' + v);

static void Main() {

Console.WriteLine('Основной поток запущен.'); data = new int[100000000];

// Инициализировать данные.

for (int i=0; i < data.Length; i++) data[i] = i;

// Поместить отрицательное значение в массив data, data[100000] = -10;

// Использовать цикл, параллельно выполняемый методом ForEachO,

// для отображения данных на экране.

ParallelLoopResult loopResult = Parallel.ForEach(data, DisplayData);

// Проверить, завершился ли цикл, if(!loopResult.IsCompleted)

Console.WriteLine('ХпЦикл завершился преждевременно из-за того, ' +

'что обнаружено отрицательное значениеп' +

'на шаге цикла номер ' +

loopResult.LowestBreaklteration + '. ');

Console.WriteLine('Основной поток завершен.');

}

}

В приведенной выше программе именованный метод применяется в качестве делегата, представляющего 'тело' цикла. Но иногда удобнее применять анонимный метод. В качестве примера ниже приведено реализуемое в виде лямбда-выражения 'тело' цикла, параллельно выполняемого методом ForEach ().

// Использовать цикл, параллельно выполняемый методом ForEachO,

// для отображения данных на экране.

ParallelLoopResult loopResult =

Parallel.ForEach(data, (v, pis) => {

Console.WriteLine('Значение: ' + v); if (v < 0) pis.Break ();

});

Исследование возможностей PLINQ

PLINQ представляет собой параллельный вариант языка интегрированных запросов LINQ и тесно связан с библиотекой TPL. PLINQ применяется, главным образом, для достижения параллелизма

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату