Одним из новых классов в .NET Framework 4.0 - является класс System.Threading.Tasks.Parallel. Этот класс поддерживает набор методов, которые позволяют выполнять итерации по коллекции данных в параллельном режиме. Одними из таких методов являются Parallel.For() и Parallel.ForEach(), Parallel.Invoke():
Все три метода блокируют управление до окончания выполнения всех действий. При возникновении необработанного исключения, в каком-то из потоков, оставшиеся рабочие потоки прекращают выполнение, и вызывается исключение - AggregationException. Основные методы класса Parallel представлены в Табл. 9.1.
| Имя | Описание |
|---|---|
| For(Int32, Int32, Action) | Выполняет цикл for, в котором итерации могут выполняться параллельно. |
| For(Int32, Int32, Action<Int32,ParallelLoopState>) | Выполняет цикл for, обеспечивая возможность параллельного выполнения итераций, а также контроля состояния цикла и управления этим состоянием. |
| ForEach(IEnumerable, Action) | Выполняет операцию foreach (For Each в Visual Basic) для объекта IEnumerable, обеспечивая возможность параллельного выполнения итераций. |
| ForEach(IEnumerable, Action<Int32,ParallelLoopState>) | Выполняет операцию foreach (For Each в Visual Basic) для объекта IEnumerable, обеспечивая возможность параллельного выполнения итераций, а также контроля состояния цикла и управления этим состоянием. |
| Invoke(Action[]) | Выполняет все предоставленные действия, в том числе параллельно. |
| Invoke(ParallelOptions, Action[]) | Выполняет каждое из указанных действий по возможности в параллельном режиме, если операция не отменена пользователем. |
Метод Parallel.Invoke() позволяет выполнять один или несколько методов, указываемых в виде его аргументов. При использовании данного метода отпадает необходимость использования метода Wait(), т.к. Invoke() сначала инициирует выполнение, а затем ожидает завершения всех передаваемых ему методов. Простая версия этого метода описана ниже:
public static void Invoke (params Action[] actions);
Существует также перегруженная версия метода Parallel.Invoke(), которая принимает объект класса ParallelOptions:
public static void Invoke (ParallelOptions options, params Action[] actions);
где optinons - объект класса ParallelOptions, с помощью которого можно добавлять маркеры (token) отмены, ограничить максимальное количество рабочих потоков или указать свой планировщик задач (custom task scheduler). Использование маркеров отмены полезно, когда число одновременно выполняемых задач превосходит количество ядер процессора: при отмене все делегаты, выполнение которых еще не было начато, будут отменены. Однако все делегаты, выполнение которых уже начато, продолжат до завершения.
Пример работы метода Invoke() представлен ниже:
static void Hello()
{
Console.WriteLine("Hello");
}
static void World()
{
Console.WriteLine("World!");
}
static void WorldHello()
{
Console.WriteLine("World Hello!");
}
static void Main(string[] args)
{
Parallel.Invoke(Hello, World, WorldHello);
Console.ReadLine();
}
(рис 9.1) Результат работы программы с использованием метода Invoke()
Метод Parallel.For() аналогичен оператору for, за исключением того что все итерации выполняются в отдельных потоках, при этом порядок выполнения итераций не определен. Конструкция данного метода представлена ниже:
Parallel.For (Int32, Int32, Action)
где первый параметр (Int32) - начальный индекс (включительно) цикла, второй параметр (Int32) - это конечный индекс (не включительно) цикла, третий параметр (Action) передаётся делегат, который вызывается один раз за итерацию. Возвращаемым типом у метода Parallel.For() является структура ParallelLoopResult, в которой содержатся сведения о выполненной части цикла.
Пример использование параллельного цикла Parallel.For() представлен ниже:
Parallel.For(0, 10, i =>
{
Console.WriteLine("{0}, Задача: {1}, Поток: {2}", i,
Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
}); Console.ReadLine();
(рис 9.2) Результат работы программы с использованием метода Parallel.For()
В одной из перегрузок этого метода Parallel.For() есть третий параметр Action<int, ParallelLoopState>. С помощью такой перегрузки метода, можно оказывать влияние на выполнение цикла с помощью методов Break() и Stop() объекта ParallelLoopState:
Stop() - применяется в алгоритмах поиска, где после нахождения результата, выполнять другие итерации не требуется;
Break() - используется для передачи циклу информации, что другие итерации после текущей итерации выполнять не требуется. Пример кода с использованием объекта ParallelLoopState представлен ниже:
Parallel.For(0, 100, (i,state) =>
{
Console.WriteLine("{0}, Задача: {1}, Поток: {2}", i,
Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
if (i == 55) state.Break();
});
(рис 9.3) Результат работы программы с использованием метода Parallel.For() и объекта ParallelLoopState
Метод Parallel.ForEach(), позволяет создавать распараллеленный вариант цикла foreach. Существует несколько форм метода Parallel.ForEach(). Одна из простых форм объявление данного метода приведена ниже:
ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body);
где source - обозначает коллекцию данных, обрабатываемых в цикле, body - метод, который будет выполняться на каждом шаге цикла.
Пример реализации метода Parallel.ForEach(), представлен ниже:
int[] data = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
Parallel.ForEach<int>(data, l =>
{
Console.WriteLine(l);
});
Console.ReadLine();
(рис 9.4) Результат работы программы с использованием метода Parallel.Foreach()
Параллельное выполнение цикла методом Parallel.ForEach() также как и метод Parallel.For(), можно остановить, вызвав метод Break() для экземпляра объекта ParallelLoopState, передаваемого через параметр body, форма метода Parallel.Foreach() приведена ниже:
ForEach<TSource>(IEnumerable<TSource> source,Action<TSource, ParallelLoopState> body);
Пример реализации метода Parallel.ForEach(), с использованием объекта ParallelLoopState представлен ниже:
char[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
ParallelLoopResult result =
Parallel.ForEach(data, (l, state) =>
{
Console.WriteLine(l);
if (l == 'e') state.Break();
});
(рис 9.5) Результат работы программы с использованием метода Parallel.Foreach() и объекта ParallelLoopState
Для того что бы получить индекс параллельной версии цикла foreach используется следующая форма метода Parallel.Foreach():
public static ParallelLoopResult ForEach<TSource> (IEnumerable<TSource> source, Action<TSource,ParallelLoopState,long> body
где long - индекс цикла.
Пример реализации метода Parallel.ForEach(), с использованием индексов цикла представлен ниже:
char[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
ParallelLoopResult result =
Parallel.ForEach(data, (l, state,i) =>
{
Console.WriteLine(l+" "+i);
});
(рис 9.6) Результат работы программы с использованием метода Parallel.Foreach() и индексов цикла
Одним из новых классов в .NET Framework 4.0 - является класс System.Threading.Tasks.Parallel. Этот класс поддерживает набор методов, которые позволяют выполнять итерации по коллекции данных в параллельном режиме. Одними из таких методов являются Parallel.For() и Parallel.ForEach(), Parallel.Invoke():
Все три метода блокируют управление до окончания выполнения всех действий. При возникновении необработанного исключения, в каком-то из потоков, оставшиеся рабочие потоки прекращают выполнение, и вызывается исключение - AggregationException. Основные методы класса Parallel представлены в Табл. 9.1.
| Имя | Описание |
|---|---|
| For(Int32, Int32, Action) | Выполняет цикл for, в котором итерации могут выполняться параллельно. |
| For(Int32, Int32, Action<Int32,ParallelLoopState>) | Выполняет цикл for, обеспечивая возможность параллельного выполнения итераций, а также контроля состояния цикла и управления этим состоянием. |
| ForEach(IEnumerable, Action) | Выполняет операцию foreach (For Each в Visual Basic) для объекта IEnumerable, обеспечивая возможность параллельного выполнения итераций. |
| ForEach(IEnumerable, Action<Int32,ParallelLoopState>) | Выполняет операцию foreach (For Each в Visual Basic) для объекта IEnumerable, обеспечивая возможность параллельного выполнения итераций, а также контроля состояния цикла и управления этим состоянием. |
| Invoke(Action[]) | Выполняет все предоставленные действия, в том числе параллельно. |
| Invoke(ParallelOptions, Action[]) | Выполняет каждое из указанных действий по возможности в параллельном режиме, если операция не отменена пользователем. |
Метод Parallel.Invoke() позволяет выполнять один или несколько методов, указываемых в виде его аргументов. При использовании данного метода отпадает необходимость использования метода Wait(), т.к. Invoke() сначала инициирует выполнение, а затем ожидает завершения всех передаваемых ему методов. Простая версия этого метода описана ниже:
public static void Invoke (params Action[] actions);
Существует также перегруженная версия метода Parallel.Invoke(), которая принимает объект класса ParallelOptions:
public static void Invoke (ParallelOptions options, params Action[] actions);
где optinons - объект класса ParallelOptions, с помощью которого можно добавлять маркеры (token) отмены, ограничить максимальное количество рабочих потоков или указать свой планировщик задач (custom task scheduler). Использование маркеров отмены полезно, когда число одновременно выполняемых задач превосходит количество ядер процессора: при отмене все делегаты, выполнение которых еще не было начато, будут отменены. Однако все делегаты, выполнение которых уже начато, продолжат до завершения.
Пример работы метода Invoke() представлен ниже:
static void Hello()
{
Console.WriteLine("Hello");
}
static void World()
{
Console.WriteLine("World!");
}
static void WorldHello()
{
Console.WriteLine("World Hello!");
}
static void Main(string[] args)
{
Parallel.Invoke(Hello, World, WorldHello);
Console.ReadLine();
}
(рис 9.1) Результат работы программы с использованием метода Invoke()
Метод Parallel.For() аналогичен оператору for, за исключением того что все итерации выполняются в отдельных потоках, при этом порядок выполнения итераций не определен. Конструкция данного метода представлена ниже:
Parallel.For (Int32, Int32, Action)
где первый параметр (Int32) - начальный индекс (включительно) цикла, второй параметр (Int32) - это конечный индекс (не включительно) цикла, третий параметр (Action) передаётся делегат, который вызывается один раз за итерацию. Возвращаемым типом у метода Parallel.For() является структура ParallelLoopResult, в которой содержатся сведения о выполненной части цикла.
Пример использование параллельного цикла Parallel.For() представлен ниже:
Parallel.For(0, 10, i =>
{
Console.WriteLine("{0}, Задача: {1}, Поток: {2}", i,
Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
}); Console.ReadLine();
(рис 9.2) Результат работы программы с использованием метода Parallel.For()
В одной из перегрузок этого метода Parallel.For() есть третий параметр Action<int, ParallelLoopState>. С помощью такой перегрузки метода, можно оказывать влияние на выполнение цикла с помощью методов Break() и Stop() объекта ParallelLoopState:
Stop() - применяется в алгоритмах поиска, где после нахождения результата, выполнять другие итерации не требуется;
Break() - используется для передачи циклу информации, что другие итерации после текущей итерации выполнять не требуется. Пример кода с использованием объекта ParallelLoopState представлен ниже:
Parallel.For(0, 100, (i,state) =>
{
Console.WriteLine("{0}, Задача: {1}, Поток: {2}", i,
Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
if (i == 55) state.Break();
});
(рис 9.3) Результат работы программы с использованием метода Parallel.For() и объекта ParallelLoopState
Метод Parallel.ForEach(), позволяет создавать распараллеленный вариант цикла foreach. Существует несколько форм метода Parallel.ForEach(). Одна из простых форм объявление данного метода приведена ниже:
ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body);
где source - обозначает коллекцию данных, обрабатываемых в цикле, body - метод, который будет выполняться на каждом шаге цикла.
Пример реализации метода Parallel.ForEach(), представлен ниже:
int[] data = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
Parallel.ForEach<int>(data, l =>
{
Console.WriteLine(l);
});
Console.ReadLine();
(рис 9.4) Результат работы программы с использованием метода Parallel.Foreach()
Параллельное выполнение цикла методом Parallel.ForEach() также как и метод Parallel.For(), можно остановить, вызвав метод Break() для экземпляра объекта ParallelLoopState, передаваемого через параметр body, форма метода Parallel.Foreach() приведена ниже:
ForEach<TSource>(IEnumerable<TSource> source,Action<TSource, ParallelLoopState> body);
Пример реализации метода Parallel.ForEach(), с использованием объекта ParallelLoopState представлен ниже:
char[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
ParallelLoopResult result =
Parallel.ForEach(data, (l, state) =>
{
Console.WriteLine(l);
if (l == 'e') state.Break();
});
(рис 9.5) Результат работы программы с использованием метода Parallel.Foreach() и объекта ParallelLoopState
Для того что бы получить индекс параллельной версии цикла foreach используется следующая форма метода Parallel.Foreach():
public static ParallelLoopResult ForEach<TSource> (IEnumerable<TSource> source, Action<TSource,ParallelLoopState,long> body
где long - индекс цикла.
Пример реализации метода Parallel.ForEach(), с использованием индексов цикла представлен ниже:
char[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
ParallelLoopResult result =
Parallel.ForEach(data, (l, state,i) =>
{
Console.WriteLine(l+" "+i);
});
(рис 9.6) Результат работы программы с использованием метода Parallel.Foreach() и индексов цикла
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.