Г. Шилдт - С#4.0 Полное руководство (1160795), страница 181
Текст из файла (страница 181)
структуры, определенной в пространстве имен еув сев. тЬгеабап№. В структуре Сапсе11аг1опТо)геп определено несколько свойств и методов, но мы воспользуемся двумя из них. Во-первых, это доступное только для чтения свойство 1зСапсе11асгоппег(пезсес(, которое объявляется следующим образом. рпЫ(с Ьоо) Гвгапсе)) ас) опяаппевсед ( Чеш ) Оно возвращает логическое значение с гпе, если отмена задачи была запрошена для вызывающего признака, а иначе — логическое значение Та 1 ее. И во-вторых, это метод ТЬгои1ГСапсе11аг1оппес(пезгес( (), который объявляется следующим образом.
разве чогп Тпговгйсапсе11аггоппеппевгеп'() Если признак отмены, для которого вызывается этот метод получил запрос на отмену, то в данном методе генерируется исключение Орегаг1опСапсе1ес(Ехсерг1оп. В противном случае никаких действий не выполняется. В отменяющем коде можно организовать отслеживание упомянутого исключения с целью убедиться в том, что отмена задачи действительно произошла. Как правило, с этой целью сначала перехватывается исключение АВ№ге№агеЕхсерггоп, а затем его внутреннее исключение анализируется с помощью свойства 1ппегехсерсьоп или 1ппегЕхсерс1опв.
(Свойство 1ппегЕхсерс1оп в представляет собой коллекцию исключений. Подробнее о коллекциях речь пойдет в главе 25.) Признак отмены получается из источника признаков отмены, который представляет собой объект класса Сапсе11асгопТокепЯопгсе, определенного в пространстве имен я уз сев.
тЬгеабьпд. Для того чтобы получить данный признак, нужно создать сначала экземпляр объекта типа Сапсе11асуопТокепЯопгсе. (С этой целью можно воспользоваться вызываемым по умолчанию конструктором класса Сап се11а СгопТо Хепэоп все ) Признак отмены, связанный с данным источником, оказывается доступным через используемое только для чтения свойство Тохеп, которое объявляется следующим образом. риЬ11с Сапсе11аггопТскеп Токеп ( Чеш ) Это и есть тот признак, который должен быть передан отменяемой задаче.
Для отмены в задаче должна быть получена копия признака отмены и организован контроль этого признака с целью отслеживать саму отмену. Такое отслеживание можно организовать тремя способами: опросом, методом обратного вызова и с помощью дескриптора ожидания. Проще всего организовать опрос, и поэтому здесь будет рассмотрен именно этот способ. С целью опроса в задаче проверяется упомянутое выше свойство 1всапсе11асвоппес(пезгег) признака отмены.
Если это свойство содержит логическое значение сгпе, значит, отмена была запрошена, и задача долж- Глава 24. Многопоточное программирование. Часть вторая. "библиотека ТРЬ 903 на быть завершена. Опрос может оказаться весьма эффективным, если организовать его правильно. Так, если задача содержит вложенные циклы, то проверка свойства 1ЯСапсе11аг1опке<(пеясес) во внешнем цикле зачастую дает лучший результат, чем его проверка на каждом шаге внутреннего цикла.
Для оидания задачи, из которой вызывается метод ТЬгоы1 ЙСапсе11а Сьопйе<)не я Ь ей ( ), когда она отменяется, обычно требуется передать признак отмены как самой задаче, так и конструктору класса Тая)<, будь то непосредственно или же косвенно через метод Ясагснеы () .
Передача признака отмены самой задаче позволяет изменить состояние отменяемой задачи в запросе на отмену из внешнего кода. Далее будет использована следующая форма метода Ягаггнеы () . роыьс таз< ягаггнен(Асгьоп<оьзесг> ассьоп, оьзесс состояние, Сапсе11асьопТо)ьеп признак отмены) В этой форме признак отмены передается через параметры, обозначаемые как состояние и признак отмены. Это означает, что признак отмены будет передан как делегату, реализующему задачу, так и самому экземпляру объекта типа Тая К. Ниже приведена форма, поддерживающая делегат Аст.ьоп.
роыьс се1ечаге чоьа Асгьоп<ьп т>(т оьз) В данном случае обобщенный параметр Т обозначает тип СЬП есС. В силу этого объект оЬ) должен быть приведен внутри задачи к типу Сапсе11агьопТо)<еп. И еще одно замечание; по завершении работы с источником признаков отмены следует освободить его ресурсы, вызвав метод ()1 ерове ( ) .
Факт отмены задачи может быть проверен самыми разными способами. Здесь применяется следующий подход: проверка значения свойства 1ЯСапсе1ег) для экземпляра объекта типа тая к. Если это логическое значение Ь где, то задача была отменена. В приведенной ниже программе демонстрируется отмена задачи. В ней применяется опрос для контроля состояния признака отмены.
Обратите внимание на то, что метод Тпгом1ТСапсе11аглопне<(пезсег(() вызывается после входа в метод МуТая К ( ) . Это дает возможность завершить задачу, если она была отмена еще до ее запуска. Внутри цикла проверяется свойство 1ясапсе11аслопнецпеясес1 Если это свойство содержит логическое значение Стае, а оно устанавливается после вызова метода Сапсе1 () для экземпляра источника признаков отмены, то на экран выводится сообщение об отмене и далее вызывается метод тьгон1тсапсе11асьоппе<(пеясе<) () для отмены задачи. Простой пример отмены задачи с использованием опроса.
ояьпо Яузсеы) ов1пс ЯувсегьТЬгеаоьпьн няьпс ЯуясеььТЬгеаоьпд.Таягю с1авв Пеыосапсе1таяк ( // Метод, исполняемый как задача. всаг1с чо1ь) Мутая)ь(ОЬЗесг сс) ( Сапсе11агьопТокеп сапсе1ток = (Сапсе11ас1опТокеп) сс) // Проверить, отменена ли задача, прежде чем запускать ее. сапсе1ТоК.ТЬгон1ГСапсе11асьопнечпеягеп()) 904 Часть П. Библиотека С№ Сопяо1е.иггсе(ьпе("МуТаяю() запущен" ) Еог(гпс соппс = 0; соппс < 10( саопсъ+) ( /! В данном примере Пля отслеживания отмены задачи применяется опрос. 11(сапсе1тоК.1ясапсе11аг1опаейоеятег() Сопяо1е.игтсестпе("Получен запрос на отмену задачи."); сапсе1тох.тьгон1йсапсе11астопйейчевтеб()( ) Твгеаб.51еер(500); Сопво1е .Хгьге( Тле ("В методе Мутаяю() подсчет равен " + сопля ); ) Сопяо1е.иг1сес1пе("Мутна)г завершен"); ясасьс чо10 Мати() ( Сопяо1е.игтсеьтпе("Основной поток запущен."); /! Создать объект источника признаков отмены.
Сапсе11астопТоьепзопгсе сапсе1тохзгс = пен Сапсе11аГ1оптоьепзоогсе() /! Запустить задачу, передав признак отмены ей самой и делегату. ТаяМ Ся)г = Таял.аассогу.зсагснен(нуТаяй, сапсе1то)гзгс.то)геп, сапсе1ТоКЯгс.Тоьеп)( Дать задаче возможность исполняться вплоть до ее отмены. Твгеаг).51еер(2000); ггу ( О Отменить задачу.
сапсе1Тохзгс.Сапсе1()( Г,( Приостановить выполнение метода Маги() до тех пор, О пока не завершится задача гя)г. Сял.иатг()( ) сапов (ЛочгеоагеЕхсерстоп ехс) ( 11(ся)г.1ясапсе1ес() Сопяоте.игггевгпе("1пзадача гяь отменена'ьп"); // Длн просмотра исключения снять комментарии со следующей строки кода: Сопяо1е.иггтеьгпе(ехс)( ) Ттпа11у ( Гях.отярояе(); сапсе1токзгс.01ярояе()( ) Сопяо1е.Хгггеььпе("Основной поток завершен."1; Ниже приведен результат выполнения этой программы.
Обратите внимание на то что задача отменяется через 2 секунды. Основной поток запущен. Мутаях() запущен Глава 24. многопоточное программирование. Часть вторая: библиотека ТРЕ 905 В методе МуТазх() В методе Мутавк() В методе Мутавк() В методе Мутазк() Получен запрос на подсчет равен О подсчет равен 1 подсчет равен 2 подсчет равен 3 отмену задачи. Задача свк отменена Основной поток завершен. Как следует из приведенного выше результата, выполнение метода МуТазй () отменяется в методе Магд () лишь две секунды спустя.
Следовательно, в методе Мутазх () выполняются четыре шага цикла. Когда же перехватывается исключение АдогедагеЕхсерглоп, проверяется состояние задачи. Если задача Сз)с отменена, что и должно произойти в данном примере, то об этом выводится соответствующее сообщение. Следует, однако, иметь в виду, что когда сообщение АддгедагеЕхсерС1оо генерируется в ответ на отмену задачи, то это еще не свидетельствует об ошибке, а просто означает, что задача была отменена. Выше были изложены лишь самые основные принципы, положенные в основу отмены задачи и генерирования исключения АддгеоагеЕхсергьод. Тем не менее эта тема намного обширнее и требует от вас самостоятельного и углубленного изучения, если вы действительно хотите создавать высокопроизводительные, масштабируемые приложения.
Другие средства организации задач В предыдущих разделах был описан ряд понятий и основных способов организации и исполнения задач. Но имеются и другие полезные средства. В частности, задачи можно делать вложенными, когда одни задачи способны создавать другие, или же порожденными, когда вложенные задачи оказываются тесно связанными с создающей их задачей. В предыдущем разделе было дано краткое описание исключения Аоогеоаге— Ехсергьоп, но у него имеются также другие особенности, которые могут оказаться весьма полезными.
К их числу относится метод Е1ассеп (), применяемый для преобразования любых внутренних исключений типа Аоо геда СеЕхсерг1оп в единственное исключение АоогедагеЕхсерггоп. Другой метод, Напс(1е (), служит для обработки исключения, составляющего совокупное исключение АоогедагеЕхсерг1оп. При создании задачи имеется возможность указать различные дополнительные параметры, оказывающие влияние на особенности ее исполнения.
Для этой цели указывается экземпляр объекта типа таз хсгеасгопОрслопз в конструкторе класса таз)с или же в фабричном методе зсагсмен () . Кроме того, в классе тавхрассогу доступно целое семейство методов Егошйз упс ( ), поддерживающих модель асинхронного программирования (АРМ вЂ” АвупсЬгопоив Ргоягатшшя Мог)е!). Как упоминалось ранее в этой главе, задачи планируются на исполнение экземпляром объекта класса Тазкэсоег)о1ег.