public static ParallelQuery AsOrdered(this ParallelQuery source)

public static ParallelQuery

           AsOrdered(this ParallelQuery source)

где TSource обозначает тип элементов в источнике данных source. Метод AsOrdered() можно вызывать только для объекта типа ParallelQuery, поскольку он является методом расширения класса ParallelQuery.

Для того чтобы посмотреть, к какому результату может привести применение метода AsOrdered(), подставьте его вызов в приведенный ниже запрос из предыдущего примера программы.

// Использовать метод AsOrdered() для сохранения порядка

// в результирующей последовательности.

var negatives = from val in data.AsParallel().AsOrdered() where val < 0 select val;

После выполнения программы порядок следования элементов в результирующей последовательности будет отражать порядок их расположения в исходной последовательности.

Отмена параллельного запроса

Параллельный запрос отменяется таким же образом, как и задача. И в том и в другом случае отмена опирается на структуру CancellationToken, получаемую из класса CancellationTokenSource. Получаемый в итоге признак отмены передается запросу с помощью метода WithCancellation(). Отмена параллельного запроса производится методом Cancel(), который вызывается для источника признаков отмены. Главное отличие отмены параллельного запроса от отмены задачи состоит в следующем: когда параллельный запрос отменяется, он генерирует исключение OperationCanceledException, а не AggregateException. Но в тех случаях, когда запрос способен сгенерировать несколько исключений, исключение OperationCanceledException может быть объединено в совокупное исключение AggregateException. Поэтому отслеживать лучше оба вида исключений.

Ниже приведена форма объявления метода WithCancellation():

public static ParallelQuery  WithCancellation (

                  this ParallelQuery source,

                             CancellationToken cancellationToken)

где source обозначает вызывающий запрос, a cancellationToken — признак отмены. Этот метод возвращает запрос, поддерживающий указанный признак отмены.

В приведенном ниже примере программы демонстрируется порядок отмены параллельного запроса, сформированного в программе из предыдущего примера. В данной программе организуется отдельная задача, которая ожидает в течение 100 миллисекунд, а затем отменяет запрос. Отдельная задача требуется потому, что цикл foreach, в котором выполняется запрос, блокирует выполнение метода Main() до завершения цикла.

// Отменить паралельный запрос

using System;

using System.Linq;

using System.Threading;

using System.Threading.Tasks;

class PLINQCancelDemo {

  static void Main() {

    CancellationTokenSource cancelTokSrc = new CancellationTokenSource();

    int[] data = new int[10000000];

    // Инициализировать массив данных положительными значениями,

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

    //А теперь ввести в массив данных ряд отрицательных значений,

    data[1000] = -1;

    data [14000] = -2;

    data[15000] = -3;

    data[676000] = -4;

    data[8024540] = -5;

    data [9908000] = -6;

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

    var negatives = from val in

          data.AsParallel(). WithCancellation(cancelTokSrc.Token)

          where val < 0

          select val;

    // Создать задачу для отмены запроса по истечении 100 миллисекунд.

    Task cancelTsk = Task.Factory.StartNew(() => {

              Thread.Sleep(100);

              cancelTokSrc.Cancel();

    });

    try {

      foreach(var v in negatives)

        Console.Write(v + " ");

    } catch(OperationCanceledException exc) {

      Console.WriteLine(exc.Message);

    } catch(AggregateException exc) {

Перейти на страницу:

Похожие книги