Асинхронный вызов метода
В многопоточном компьютерном программировании асинхронный вызов метода ( AMI ), также известный как асинхронные вызовы методов или асинхронный шаблон, представляет собой шаблон проектирования , в котором место вызова не блокируется во время ожидания завершения вызываемого кода. Вместо этого вызывающий поток уведомляется о поступлении ответа. Опрос для получения ответа — нежелательный вариант.
Фон
[ редактировать ]AMI — это шаблон проектирования для асинхронного долго выполняющихся методов объекта вызова потенциально . [1] Это эквивалентно шаблону долговой расписки («Я вам должен»), описанному в 1996 году Алланом Вермюленом. [2] [3]
В большинстве языков программирования вызываемый метод выполняется синхронно, т.е. в потоке выполнения, из которого он вызывается. Если выполнение метода занимает много времени, например, из-за загрузки данных через Интернет, вызывающий поток блокируется до тех пор, пока метод не завершится. Если это нежелательно, можно запустить «рабочий поток» и вызвать метод оттуда. В большинстве сред программирования для этого требуется много строк кода, особенно если принять меры, чтобы избежать накладных расходов, которые могут быть вызваны созданием большого количества потоков. AMI решает эту проблему тем, что дополняет потенциально долго выполняющийся («синхронный») объектный метод «асинхронным» вариантом, который возвращает немедленный результат, а также дополнительными методами, которые упрощают получение уведомления о завершении или ожидание завершения в момент завершения. более позднее время.
Одним из распространенных вариантов использования AMI является шаблон проектирования активных объектов . Альтернативами являются синхронный вызов метода и будущие объекты . [4] Примером приложения, которое может использовать AMI, является веб-браузер, которому необходимо отображать веб-страницу еще до загрузки всех изображений.
Поскольку метод является частным случаем процедуры , асинхронный вызов метода является частным случаем асинхронного вызова процедуры .
Реализации
[ редактировать ]Java-класс
[ редактировать ]Класс FutureTask [5] в Java используйте события для решения той же проблемы. Этот шаблон представляет собой вариант AMI, реализация которого требует больше накладных расходов, но он полезен для объектов, представляющих компоненты программного обеспечения .
.NET Framework
[ редактировать ]- Шаблон модели асинхронного программирования (APM) (использовался до .NET Framework 2.0) [6]
- Асинхронный шаблон на основе событий (EAP) (используется в .NET Framework 2.0) [7]
- Асинхронный шаблон на основе задач (TAP) (используется в .NET Framework 4.0) [8]
Пример
[ редактировать ]Следующий пример во многом основан на стандартном стиле AMI, используемом в .NET Framework . [9]
Учитывая метод Accomplish
, добавляется два новых метода BeginAccomplish
и EndAccomplish
:
class Example
{
Result Accomplish(args …)
IAsyncResult BeginAccomplish(args …)
Result EndAccomplish(IAsyncResult a)
…
}
При звонке BeginAccomplish
, клиент сразу получает объект типа AsyncResult
(который реализует IAsyncResult
интерфейс), чтобы он мог продолжить вызывающий поток, выполняя несвязанную работу. В самом простом случае со временем такой работы больше нет, и клиент звонит EndAccomplish
(передача ранее полученного объекта), который блокируется до тех пор, пока метод не завершится и результат не станет доступным. [10] AsyncResult
объект обычно предоставляет по крайней мере метод, который позволяет клиенту запрашивать, завершился ли уже длительный метод:
interface IAsyncResult
{
bool HasCompleted()
…
}
Также можно передать метод обратного вызова BeginAccomplish
, который будет вызываться после завершения длительного метода. Обычно он вызывает EndAccomplish
чтобы получить возвращаемое значение долговыполняющегося метода. Проблема с механизмом обратного вызова заключается в том, что функция обратного вызова естественным образом выполняется в рабочем потоке (а не в исходном вызывающем потоке), что может вызвать состояние гонки. [11] [12]
В документации .NET Framework термин «асинхронный шаблон на основе событий» относится к альтернативному стилю API (доступен начиная с .NET 2.0), использующему метод с именем AccomplishAsync
вместо BeginAccomplish
. [13] [14]
Поверхностное отличие состоит в том, что в этом стиле возвращаемое значение долговыполняющегося метода передается непосредственно методу обратного вызова. Гораздо важнее то, что API использует специальный механизм для запуска метода обратного вызова (который находится в объекте события типа AccomplishCompleted
) в той же теме, в которой BeginAccomplish
позвонили. Это устраняет опасность возникновения гонок, делая API более простым в использовании и подходящим для программных компонентов; с другой стороны, эта реализация шаблона сопряжена с дополнительными накладными расходами на создание и синхронизацию объектов. [15]
Ссылки
[ редактировать ]- ^ «Асинхронный вызов метода» . Распределенное программирование с помощью Ice . ZeroC, Inc. Архивировано из оригинала 5 января 2008 года . Проверено 22 ноября 2008 г.
- ^ Вермюлен, Аллан (июнь 1996 г.). «Шаблон асинхронного проектирования» . Журнал доктора Добба . Проверено 22 ноября 2008 г.
- ^ Нэш, Трей (2007). «Потоки в C#». Ускоренный C# 2008 . Апресс. ISBN 978-1-59059-873-3 .
- ^ Лаванда, Р. Грег; Дуглас К. Шмидт . «Активный объект» (PDF) . Архивировано из оригинала (PDF) 22 июля 2012 г. Проверено 22 ноября 2008 г.
{{cite journal}}
: Для цитирования журнала требуется|journal=
( помощь ) - ^ «Класс FutureTask» . Оракул. 2011. Архивировано из оригинала 25 июня 2013 г. Проверено 29 июня 2015 г.
- ^ «Модель асинхронного программирования» . Майкрософт. 2015 . Проверено 29 июня 2015 г.
- ^ «Обзор асинхронного шаблона на основе событий» . Майкрософт. 2015 . Проверено 29 июня 2015 г.
- ^ «Асинхронный шаблон на основе задач» . Майкрософт. 2015 . Проверено 29 июня 2015 г.
- ^ «Шаблоны проектирования асинхронного программирования» . Руководство разработчика .NET Framework . Сеть разработчиков Microsoft. Архивировано из оригинала 22 ноября 2008 года . Проверено 22 ноября 2008 г.
- ^ «Обзор асинхронного программирования» . Руководство разработчика .NET Framework . Сеть разработчиков Microsoft. Архивировано из оригинала 7 декабря 2008 года . Проверено 22 ноября 2008 г.
- ^ «Использование делегата AsyncCallback для завершения асинхронной операции» . Руководство разработчика .NET Framework . Сеть разработчиков Microsoft. Архивировано из оригинала 23 декабря 2008 года . Проверено 22 ноября 2008 г.
- ^ «Проблемы параллелизма» . Распределенное программирование с помощью Ice . ZeroC, Inc. Архивировано из оригинала 28 марта 2008 года . Проверено 22 ноября 2008 г.
- ^ Кристиан Нагель; Билл Эвджен; Джей Глинн; Карли Уотсон и Морган Скиннер (2008). «Асинхронный шаблон на основе событий». Профессиональный C# 2008 . Уайли. стр. 570–571 . ISBN 9780470191378 .
- ^ «Многопоточное программирование с использованием асинхронного шаблона на основе событий» . Руководство разработчика .NET Framework . Сеть разработчиков Microsoft. Архивировано из оригинала 25 декабря 2008 года . Проверено 22 ноября 2008 г.
- ^ «Решение, когда реализовать асинхронный шаблон на основе событий» . Руководство разработчика .NET Framework . Сеть разработчиков Microsoft. Архивировано из оригинала 22 ноября 2008 года . Проверено 22 ноября 2008 г.
Дальнейшее чтение
[ редактировать ]- Крис Селлс и Ян Гриффитс (2007). «Приложение C.3: Асинхронный шаблон на основе событий». Программирование WPF . О'Рейли. стр. 747–749 . ISBN 9780596510374 .
- Использование асинхронных вызовов методов в C#