Вопрос по Курсу: "Параллельное программирование с использованием MS VisualStudia 2010". При компиляции Самостоятельного задания (одновременная отрисовка прямоугольников, эллипсов и выдача в текст-бокс случайного числа) среда предупреждает: suspend - устаревшая команда; примените monitor, mutex и т.п. Создаётся впечатление, что Задание создано в более поздней среде, чем VS 2010. |
Параллелизм задач
Введение
Параллелизм задач (task parallelism) - это низкоуровневый подход к распараллеливанию задач с помощью PFX. Классы этого уровня определены в пространстве имен System.Threading.Tasks (Табл. 7.1).
Класс | Описание |
---|---|
Task | Представляет асинхронную операцию. |
Task <TResult> | Представляет асинхронную операцию, которая возвращает значение. |
TaskScheduler | Объект, обрабатывающий низкоуровневую постановку задач в очередь на потоки. |
TaskFactory | Для создания объекта Task. |
TaskFactory <TResult> | Для создания объекта Task, с возвращаемым значением. |
Создание и запуск задачи
Как уже писалось в "Введение в асинхронные задачи" задачи можно создавать различными способами. Один из таких способов - это использование лямда-выражения и метода Task.Factory.StartNew():
Task.Factory.StartNew (() => Console.WriteLine ("Hello World!"));
Аналогично, можно было вывести на экран сообщение "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("Родительская задача выполнена");
Наиболее важным моментом при сравнении дочерних и вложенных задач является то, что вложенные задачи по существу не зависят от родительской или внешней задачи, тогда как вложенные дочерние задачи синхронизируются с родительской задачей. Если изменить оператор создания задач так, чтобы использовался параметр 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