Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Библиотека параллельных задач
Библиотека параллельных задач - TPL (Task Parallel Library), представленная в четвертой версии. Net Framework 4.0, позволяет справиться как с проблемой синхронизации задач, выполняемых в пуле потоков, так и предоставить много новых дополнительных возможностей. На сегодняшний день лучший способ создания многопоточного приложения предполагает работу с объектами библиотеки TPL. Понятие " задача" является одним из центральных понятий в параллельном программировании. Распараллеливание " по задачам" и распараллеливание " по данным" - два основных принципа параллельных вычислений. Вполне естественно введение класса Task, объекты которого представляют задачи. В. Net Framework 4.0 в пространстве имен Threading выделено пространство Threading.Tasks, содержащее как класс Task, так и другие классы, поддерживающие работу с задачами, возможности их параллельного выполнения. Эти классы, являясь надстройкой над пулом потоков, позволяют полностью абстрагироваться от " потоков" - низкоуровневых механизмов и сосредоточиться на работе с объектами более высокого уровня - " задачами", отражающими суть приложения. Тем не менее, корректная работа с задачами предполагает, а на самом деле невозможна без понимания всех проблем, присущих параллельным вычислениям - синхронизации, блокировкам, гонки данных и клинчам. Требования к методам для задач остаются прежними. Методы, как и ранее, могут быть трех типов. Это может быть метод с фиксированной сигнатурой void (object). Это может быть метод с такой же сигнатурой, вызываемый объектом некоторого класса. Это может быть анонимный метод с такой же сигнатурой, способный вызвать метод с произвольной сигнатурой. Прежде чем формально описать возможности класса Task и других классов пространства System.Threading.Tasks, давайте модифицируем наш предыдущий пример с несколькими работниками, выразив его в терминах задач, не обращаясь явно к пулу потоков. // Создание первой задачи task1 //С задачей связывается анонимный метод, //вызывающий метод с произвольной сигнатурой string res =" "; Task task1 = new Task((object inf) => { WorkerOne(" Дмитрий", 33, inf, out res); }, " отличный работник"); //Запуск задачи и ожидание ее завершения task1.Start(); task1.Wait(); //Печать результатов работы метода в основном потоке Console.WriteLine(res); В целом схема работы с задачей проста и естественна. Создается объект task1, характеризующий задачу. В момент создания с ним связывается метод, который должна выполнить задача. Затем задача стартует. Основной поток в этот момент приостанавливается, ожидая завершения задачи. Когда это событие происходит, основной поток продолжает свое выполнение, выводя на консоль результаты решения задачи task1. Рассмотрим теперь вторую возможность - передачу задаче метода с фиксированной сигнатурой void (object). При создании задачи конструктору класса Task передаются два параметра. Первый параметр функционального типа, задаваемый делегатом Action, несет информацию о методе, второй параметр типа object передает методу всю входную информацию, необходимую для работы метода. Task.WaitAll - Ожидает завершения выполнения всех указанных объектов Task. Класс Task< TResult> представляет асинхронную операцию, которая может вернуть значение. Задачи просто запускаются на параллельное выполнение. При этом нам нет необходимости думать о числе процессоров компьютера, о потоках операционной системы. Вся работа идет на высоком абстрактном уровне объектов, отвечающих сути нашего приложения. Вопросы синхронизации работы задач решаются просто. У класса Task десяток свойств. Группа свойств Is позволяет выяснить закончилась ли задача, по какой причине она закончилась - вследствие возникшей ошибки или снята по требованию родительской задачи. Статическое свойство Factory открывает доступ к фабричным методам. В частности важную роль играет метод Task.Factory.StartNew, который позволяет создать новую задачу и запустить на выполнение. Считается, что такой способ выигрывает по производительности в сравнении с подходом, применяемым в наших примерах, когда создание задачи и ее запуск разделены. У класса есть несколько десятков методов. С основными методами Start и Wait мы познакомились. У каждого из этих методов есть ряд модификаций. Ждать завершения задачи можно не бесконечно долго, а лишь в течение заданного интервала времени, после чего предпринимать определенные действия. Большую группу составляют методы ContinueWith, позволяющие организовать цепочку исполняемых задач, когда по завершении одной задачи начинает выполняться преемник задачи. Более того, преемник задачи может в качестве входных данных использовать результаты работы предшественника. Статические методы WaitAll и WaitAny в разных модификациях позволяют организовать ожидание для массива задач. Конечно же, предусмотрена обработка исключительных ситуаций, возникающих при выполнении задач. Есть свойство Exception, свойство IsFaulted, есть классы, задающие соответствующие исключительные ситуации.
|