Общие сведения об асинхронном программировании
Обновлен: Ноябрь 2007
Асинхронная операция, использующая шаблон разработки IAsyncResult, реализуется в виде двух методов с именами Beginимя_операции и Endимя_операции, которые соответственно начинают и завершают асинхронную операцию имя_операции. Например, класс FileStream предоставляет методы BeginRead и EndRead для асинхронного считывания байт из файла. Эти методы реализуют асинхронную версию метода Read.
После вызова метода Beginимя_операции приложение может продолжить выполнение инструкций в вызывающем потоке, пока асинхронная операция выполняется в другом потоке. Для каждого вызова метода Beginимя_операции в приложении также должен присутствовать вызов метода Endимя_операции, чтобы получить результаты операции.
Начало асинхронной операции
Метод Beginимя_операции начинает асинхронную операцию имя_операции и возвращает объект, реализующий интерфейс IAsyncResult. В объектах IAsyncResult хранятся сведения об асинхронной операции. В следующей таблице показаны данные об асинхронной операции.
Элемент |
Описание |
---|---|
Дополнительный объект, связанный с приложением, который содержит сведения об асинхронной операции. |
|
Объект WaitHandle, который можно использовать, чтобы заблокировать выполнение приложения до завершения асинхронной операции. |
|
Значение, показывающее, что асинхронная операция выполнена в потоке, используемом для вызова метода Beginимя_операции, а не в отдельном потоке ThreadPool. |
|
Значение, показывающее, выполнена ли асинхронная операция. |
Метод Beginимя_операции принимает любые параметры, объявленные в подписи синхронной версии метода, которые передаются по значению или по ссылке. Параметры out не входят в подпись метода Beginимя_операции. В подпись метода Beginимя_операции также входят два дополнительных параметра. Первый из них определяет делегат AsyncCallback, который ссылается на метод, вызываемый при завершении асинхронной операции. Вызывающий объект может указать значение null (Nothing в Visual Basic), если не нужно вызывать метод при завершении операции. Вторым дополнительным параметром является определяемый пользователем объект. Этот объект можно использовать для передачи сведений о состоянии, относящихся к приложению, в метод, который вызывается при завершении асинхронной операции. Если метод Beginимя_операции принимает дополнительные параметры, относящиеся к операции, например массив байт для хранения байт, считываемых из файла, то объект AsyncCallback и объект состояния приложения являются последними параметрами в подписи метода Beginимя_операции.
Метод Beginимя_операции немедленно возвращает управление в вызывающий поток. Если метод Beginимя_операции создает исключения, то исключения вызываются перед запуском асинхронной операции. Если метод Beginимя_операции создает исключения, метод обратного вызова не вызывается.
Завершение асинхронной операции
Метод Endимя_операции завершает асинхронную операцию имя_операции. Возвращаемое значение метода Endимя_операции имеет тот же тип, что и значение его синхронной версии, и определяется асинхронной операцией. Например метод EndRead возвращает число байт, считанных из потока FileStream, а метод EndGetHostByName возвращает объект IPHostEntry, содержащий сведения о сервере. Метод Endимя_операции принимает любые выходные параметры out и ref, объявленные в подписи синхронной версии метода. Помимо параметров из синхронного метода, метод Endимя_операции также включает параметр IAsyncResult. Вызывающие объекты должны передавать экземпляр, возвращаемый соответствующим вызовом метода Beginимя_операции.
Если асинхронная операция, представленная объектом IAsyncResult, не выполнена к моменту вызова метода Endимя_операции, то метод Endимя_операции блокирует выполнение вызывающего потока до момента завершения асинхронной операции. Исключения, создаваемые асинхронной операции, вызываются из метода Endимя_операции. Многократный вызов метода Endимя_операции с одним экземпляром IAsyncResult приводит к неопределенному эффекту. Аналогично, вызов метода Endимя_операции с объектом IAsyncResult, который не был возвращен соответствующим методом Begin, также имеет неопределенный эффект.
Примечание. |
---|
В случае реализации этих неопределенных сценариев рекомендуется вызывать исключение InvalidOperationException. |
Примечание. |
---|
В случае реализации этого шаблона разработки необходимо уведомить вызывающий объект о завершении асинхронной операции, установив свойство IsCompleted в значение true, вызвав асинхронный метод обратного вызова (если он указан) и отправив сигнал AsyncWaitHandle. |
Разработчики приложений имеют выбор способов доступа к результатам асинхронной операции. Правильный выбор зависит от того, содержит ли приложение инструкции, которые могут выполняться, пока не завершена операция. Если приложение не может выполнять никакую дополнительную работу, пока не получены результаты асинхронной операции, его необходимо заблокировать до момента, когда станут доступны результаты. Чтобы заблокировать работу до завершения асинхронной операции, используется один из следующих способов.
Вызовите метод Endимя_операции из главного потока приложения, чтобы заблокировать выполнение приложения до завершения операции. Пример, демонстрирующий этот способ, см. в разделе Блокирование выполнения приложения путем завершения асинхронной операции.
Используйте свойство AsyncWaitHandle, чтобы заблокировать выполнение приложения до завершения одной или нескольких операций. Пример, демонстрирующий этот способ, см. в разделе Блокирование выполнения приложения с помощью AsyncWaitHandle.
В приложениях, которые не нужно блокировать до завершения асинхронной операции, можно использовать один из следующих способов.
Запрашивайте состояние выполнения операции, периодически проверяя свойство IsCompleted, и вызовите метод Endимя_операции, когда операция будет завершена. Пример, демонстрирующий этот способ, см. в разделе Запрос состояния асинхронной операции.
Используйте делегат AsyncCallback для указания метода, который должен вызываться при завершении операции. Пример, демонстрирующий этот способ, см. в разделе Использование делегата AsyncCallback для завершения асинхронной операции.
См. также
Основные понятия
Асинхронный вызов синхронных методов
Использование делегата AsyncCallback и объекта состояния