Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 253 254 255 256 257 258 259 260 261 ... 294

Для того чтобы посмотреть, к какому результату может привести применение метода 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<TSource>  WithCancellation<TSource> (

                  this ParallelQuery<TSource> 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) {

      Console.WriteLine (exc);

    } finally {

      cancelTsk.Wait();

      cancelTokSrc.Dispose();

      cancelTsk.Dispose();

    }

    Console.WriteLine();

  }

}

Ниже приведен результат выполнения этой программы. Если запрос отменяется до его завершения, то на экран выводится только сообщение об исключительной ситуации.

Запрос отменен с помощью маркера, переданного в метод WithCancellation.

Другие средства PLINQ

Как упоминалось ранее, PLINQ представляет собой довольно крупную подсистему. Это объясняется отчасти той гибкостью, которой обладает PLINQ. В PLINQ доступны и многие другие средства, помогающие подстраивать параллельные запросы под конкретную ситуацию. Так, при вызове метода WithDegreeOfParallelism() можно указать максимальное количество процессоров, выделяемых для обработки запроса, а при вызове метода AsSequential() — запросить последовательное выполнение части параллельного запроса. Если вызывающий поток, ожидающий результатов от цикла foreach, не требуется блокировать, то для этой цели можно воспользоваться методом ForAll(). Все эти методы определены в классе ParallelEnumerable. А в тех случаях, когда PLINQ должен по умолчанию поддерживать последовательное выполнение, можно воспользоваться методом WithExecutionMode(), передав ему в качестве параметра признак ParallelExecutionMode.ForceParallelism.

Вопросы эффективности PLINQ

Далеко не все запросы выполняются быстрее только потому, что они распараллелены. Как пояснялось ранее в отношении TPL, издержки, связанные с созданием параллельных потоков и управлением их исполнением, могут "перекрыть" все преимущества, которые дает распараллеливание. Вообще говоря, если источник данных оказывается довольно мелким, а требующаяся обработка данных — очень короткой, то внедрение параллелизма может и не привести к ускорению обработки запроса. Поэтому за рекомендациями по данному вопросу следует обращаться к информации корпорации Microsoft.

ГЛАВА 25 Коллекции, перечислители и итераторы

В этой главе речь пойдет об одной из самых важных составляющих среды .NET Framework: коллекциях. В C# коллекция представляет собой совокупность объектов. В среде .NET Framework имеется немало интерфейсов и классов, в которых определяются и реализуются различные типы коллекций. Коллекции упрощают решение многих задач программирования благодаря тому, что предлагают готовые решения для создания целого ряда типичных, но порой трудоемких для разработки структур данных. Например, в среду .NET Framework встроены коллекции, предназначенные для поддержки динамических массивов, связных списков, стеков, очередей и хеш-таблиц. Коллекции являются современным технологическим средством, заслуживающим пристального внимания всех, кто программирует на С#.

Первоначально существовали только классы необобщенных коллекций. Но с внедрением обобщений в версии C# 2.0 среда .NET Framework была дополнена многими новыми обобщенными классами и интерфейсами. Благодаря введению обобщенных коллекций общее количество классов и интерфейсов удвоилось. Вместе с библиотекой распараллеливания задач (TPL) в версии 4.0 среды .NET Framework появился ряд новых классов коллекций, предназначенных для применения в тех случаях, когда доступ к коллекции осуществляется из нескольких потоков. Нетрудно догадаться, что прикладной интерфейс Collections API составляет значительную часть среды .NET Framework.

Кроме того, в настоящей главе рассматриваются два средства, непосредственно связанные с коллекциями: перечислители и итераторы. И те и другие позволяют поочередно обращаться к содержимому класса коллекции в цикле foreach.

Краткий обзор коллекций

Главное преимущество коллекций заключается в том, что они стандартизируют обработку групп объектов в программе. Все коллекции разработаны на основе набора четко определенных интерфейсов. Некоторые встроенные реализации таких интерфейсов, в том числе ArrayList, Hashtable, Stack и Queue, могут применяться в исходном виде и без каких-либо изменений. Имеется также возможность реализовать собственную коллекцию, хотя потребность в этом возникает крайне редко.

В среде .NET Framework поддерживаются пять типов коллекций: необобщенные, специальные, с поразрядной организацией, обобщенные и параллельные. Необобщенные коллекции реализуют ряд основных структур данных, включая динамический массив, стек, очередь, а также словари, в которых можно хранить пары "ключ-значение". В отношении необобщенных коллекций важно иметь в виду следующее: они оперируют данными типа object.

1 ... 253 254 255 256 257 258 259 260 261 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий