Создание вложенных задач




Параллелизм задач

Введение

Параллелизм задач (task parallelism) - это низкоуровневый подход к распараллеливанию задач с помощью PFX. Классы этого уровня определены в пространстве имен System. Threading.Tasks (Табл. 7.1).

Таблица 7.1. Основные классы пространства имен System.Threading.Task
Класс Описание
Task Представляет асинхронную операцию.
Task <TResult> Представляет асинхронную операцию, которая возвращает значение.
TaskScheduler Объект, обрабатывающий низкоуровневую постановку задач в очередь на потоки.
TaskFactory Для создания объекта Task.
TaskFactory <TResult> Для создания объекта Task, с возвращаемым значением.

Создание и запуск задачи

Как уже писалось в "Введение в асинхронные задачи" задачи можно создавать различными способами. Один из таких способов - это использование лямда-выражения и метода Task.Factory.StartNew():

Task.Factory.StartNew (() => Console.WriteLine ("Hello World!"));


увеличить изображение
Рис. 7.1. Результат выполнения программы с использованием класса Task

Аналогично, можно было вывести на экран сообщение "Hello World!", вначале создав объект Task, а затем вызвав метод Start():

Task task = new Task (() => Console.Write ("Hello World!"));

task.Start();

Что бы выполнить задачу синхронно (в том же потоке) небходимо вызвать метод RunSynchronously() вместо вызова метода Start():

Task task = new Task (() => Console.Write ("Hello World!"));

task.RunSynchronously()

Класс Task <TResult>, позволяет получить определенный набор данных после завершения выполнения задачи:

Task<int> task = Task.Factory.StartNew< int > (()

{

int i,c,j;

c=5;

j=5;

i=c+j;

return i;

});

 

DoSomething(); // Выполнение другой операции асинхронно

Console.WriteLine("Результат выполнения задачи:"+task.Result);

Console.ReadLine();


увеличить изображение
Рис. 7.2. Результат выполнения программы с использованием класса Task <TResult>

Создание вложенных задач

Вложенные задача - это экземпляр задачи Task, создаваемый в пользовательском делегате другой задачи. Дочерняя задача - это вложенная задача, создаваемая с помощью параметра AttachedToParent. Задача может создать любое количество дочерних и вложенных задач, ограничиваясь только системными ресурсами. Пример кода, демонстрирующий создание вложенных задач, представлен ниже:

Task parent = Task.Factory.StartNew(() =>

{

Console.WriteLine("Родительская задача запущена");

 

Task.Factory.StartNew(() => // Дочерняя задача

{

Console.WriteLine("Дочерняя задача запущена");

Thread.SpinWait(5000000);

Console.WriteLine("Дочерняя задача выполнена");

 

});

});

parent.Wait();

Console.WriteLine("Родительская задача выполнена");


увеличить изображение
Рис. 7.3. Результат выполнения программы с использованием дочерних задач

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

Task parent = Task.Factory.StartNew(() =>

{

Console.WriteLine("Родительская задача запущена");

 

Task.Factory.StartNew(() => // Дочерняя задача

{

Console.WriteLine("Дочерняя задача запущена");

Thread.SpinWait(5000000);

Console.WriteLine("Дочерняя задача выполнена");

 

}, TaskCreationOptions.AttachedToParent);

});

parent.Wait();

Console.WriteLine("Родительская задача выполнена");


увеличить изображение
Рис. 7.4. Результат выполнения программы с использованием дочерних задач и параметра AttachedToParent

Ожидание задач

Возможно, осуществлять ожидание выполнения задач двумя различными способами:

· С помощью метода Wait(). Один из возможных форматов объявления этого метода представлен ниже:

public Wait(TimeSpan timeout)

где timeout - время ожидания в миллисекундах.

· C помощью обращения к свойству Result (свойство класса Task<TResult>):

public TResult Result;

Можно также одновременно ожидать завершения нескольких задач с помощью метода Task.WaitAll() который ожидает завершения всех указанных задач и метода Task.WaitAny() который ожидает завершения какой-либо задачи. Форматы объявления этих методов представлены ниже:

Public static void WaitAll(Task[]);

Public static void WaitAny(Task[]);

где Task[] - массив экземпляров класса Task.

Метод WaitAll() ожидает выполнение всех остальных задач, по завершению работы задач вызывает исключение типа AggregateException, которое содержит все исключения неудачно завершившихся задач.

Вызов метода WaitAny() эквивалентен ожиданию ManualResetEventSlim, который переводится в сигнальное состояние при завершении конкретной задачи.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-06-11 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: