Асинхронная модель

Большинство операций в API веб-служб Windows можно выполнять синхронно или асинхронно. Чтобы вызвать функцию синхронно, передайте значение NULL для структуры WS_ASYNC_CONTEXT . Чтобы указать, что функция может выполняться асинхронно, передайте WS_ASYNC_CONTEXT не null.

При асинхронном вызове функция может выполняться синхронно или асинхронно. Если функция завершается синхронно, она возвращает значение, указывающее на окончательный успех или ошибку, и это значение всегда отличается от WS_S_ASYNC (см. раздел Возвращаемые значения веб-служб Windows). Однако возвращаемое значение WS_S_ASYNC указывает, что функция будет выполняться асинхронно. Когда функция завершается асинхронно, вызывается обратный вызов, чтобы сообщить о завершении операции. Этот обратный вызов указывает окончательное значение успешного выполнения или ошибки. Обратный вызов не вызывается, если операция завершается синхронно.

Чтобы создать асинхронный контекст, инициализируйте поля callback и callbackStateструктуры WS_ASYNC_CONTEXT . Поле callbackState используется для указания указателя на определяемые пользователем данные, которые передаются в функцию WS_ASYNC_CALLBACK .

В следующем примере показано асинхронное вызов функции путем передачи указателя на структуру WS_ASYNC_CONTEXT , содержащую обратный вызов и указатель на данные состояния.

HRESULT ExampleAsyncFunction(WS_ASYNC_CONTEXT* asyncContext);
void ExampleAsyncFunction()
{
    // Set up the WS_ASYNC_CONTEXT structure.
    MyState* myState = ...;  \\ Declare a pointer to user-defined data.
    WS_ASYNC_CONTEXT asyncContext;
    asyncContext.callback = MyCallback;  \\ Set the callback.
    asyncContext.callbackState = myState; \\ Set the pointer to the user-defined data.

    // Start the asynchronous operation
    HRESULT hr = SomeFunction(&asyncContext);

    if (hr == WS_S_ASYNC)
    {
        // The operation is completing asynchronously.  The callback is called 
        // when the operation is complete.
    }
    else
    {
        // The operation completed synchronously.  The callback is not called.
    }
}
void CALLBACK MyCallback(HRESULT hr, WS_CALLBACK_MODEL callbackModel, void* callbackState)
{
    MyState* myState = (MyState*)callbackState;

    // The operation completed asynchronously.
}

Структура WS_ASYNC_CONTEXT используется асинхронной функцией только на протяжении всего вызова функции (не в течение асинхронной операции), поэтому ее можно безопасно объявить в стеке.

Если какие-либо другие параметры, кроме структуры WS_ASYNC_CONTEXT , передаются в асинхронную функцию в качестве указателей и функция завершается асинхронно, вызывающий объект отвечает за поддержание активности значений, на которые указывают эти параметры (не освобождается), пока не будет вызван асинхронный обратный вызов.

Существуют ограничения на операции, которые может выполнять обратный вызов. Дополнительные сведения о возможных операциях см. в WS_CALLBACK_MODEL.

При реализации асинхронной функции не вызывайте обратный вызов в том же потоке, который вызвал асинхронную функцию до возврата асинхронной функции вызывающей стороне, так как это нарушает асинхронную модель.

При реализации функции, которая должна выполнять ряд асинхронных операций, рассмотрите возможность использования вспомогательной функции WsAsyncExecute .

В примере асинхронной функции показано, как реализовать и использовать функции, которые соответствуют асинхронной модели.

Запуск асинхронной операции ввода-вывода потребляет системные ресурсы. Если запущено достаточно операций ввода-вывода, система может перестать отвечать. Чтобы избежать этого, приложению необходимо ограничить количество запускаемых асинхронных операций.

В асинхронной модели используются следующие элементы API.

Обратный вызов Описание
WS_ASYNC_CALLBACK Параметр функции обратного вызова, используемый с асинхронной моделью.
WS_ASYNC_FUNCTION Используется с WsAsyncExecute для указания следующей функции, вызываемой в серии асинхронных операций.

 

Перечисление Описание
WS_CALLBACK_MODEL Задает поведение потоков обратного вызова (например, WS_ASYNC_CALLBACK).

 

Функция Описание
WsAsyncExecute Вызывает определяемый пользователем обратный вызов, который может инициировать асинхронную операцию и указывать функцию, которая должна вызываться после завершения асинхронной операции.

 

Структура Описание
WS_ASYNC_CONTEXT Задает асинхронный обратный вызов и указатель на определяемые пользователем данные, которые будут переданы в асинхронный обратный вызов.
WS_ASYNC_OPERATION Используется с WsAsyncExecute для указания следующей функции, вызываемой в серии асинхронных операций.
WS_ASYNC_STATE Используется WsAsyncExecute для управления состоянием асинхронной операции.

 

Пример асинхронной функции

WS_ASYNC_CALLBACK

WS_ASYNC_CONTEXT

WS_CALLBACK_MODEL

WsAsyncExecute