Asynchronous Model

Most operations in Windows Web Services API can be performed synchronously or asynchronously. To call a function synchronously, pass a null value for the WS_ASYNC_CONTEXT structure. To specify that a function may be performed asynchronously, pass a non-null WS_ASYNC_CONTEXT to the function.

When called asynchronously, a function can nevertheless complete synchronously or asynchronously. If the function completes synchronously, it returns a value that indicates the final success or error, and this value is always something other than WS_S_ASYNC (See Windows Web Services Return Values). A return value of WS_S_ASYNC, however, indicates that the function will complete asynchronously. When the function completes asynchronously, a callback is invoked to signal completion of the operation. This callback indicates the final success or error value. The callback is not called if the operation completes synchronously.

To create an asynchronous context, initialize the callback and callbackState fields of the WS_ASYNC_CONTEXT structure. The callbackState field is used to specify a pointer to user-defined data which is passed to the WS_ASYNC_CALLBACK function.

The following example shows calling a function asynchronously by passing a pointer to a WS_ASYNC_CONTEXT structure that contains the callback and a pointer to the state data.

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.
}

The WS_ASYNC_CONTEXT structure is used by the asynchronous function only for the duration of the function call (not for the duration of the asynchronous operation), so you can safely declare it on the stack.

If any other parameters, besides the WS_ASYNC_CONTEXT structure, are passed to an asynchronous function as pointers and the function completes asynchronously, it is the responsibility of the caller to keep the values pointed to by these parameters alive (not freed) until the asynchronous callback is invoked.

There are limitations on what operations a callback may perform. For more information on possible operations , see the WS_CALLBACK_MODEL.

When you implement an asynchronous function, do not invoke the callback on the same thread that called the asynchronous function before the asynchronous function has returned to the caller, as this disrupts the asynchronous model.

When implementing a function that needs to execute a series of asynchronous operations, consider using the WsAsyncExecute helper function.

The Asynchronous Function Example shows how to implement and consume functions that follow the asynchronous model.

Starting an asynchronous IO operation consumes system resources. If enough IO operations are started, the system can become unresponsive. To prevent this, an application needs to limit the number of asynchronous operations that it starts.

The asynchronous model uses the following API elements.

Callback Description
WS_ASYNC_CALLBACK The callback function parameter used with the asynchronous model.
WS_ASYNC_FUNCTION Used with the WsAsyncExecute to specify the next function to invoke in a series of asynchronous operations.

 

Enumeration Description
WS_CALLBACK_MODEL Specifies the threading behavior of a callback (for example, a WS_ASYNC_CALLBACK).

 

Function Description
WsAsyncExecute Invokes a user-defined callback which can initiate an asynchronous operation and indicate a function that should be called when the asynchronous operation has been completed.

 

Structure Description
WS_ASYNC_CONTEXT Specifies the asynchronous callback and a pointer to user-defined data, which will be passed to the asynchronous callback.
WS_ASYNC_OPERATION Used with the WsAsyncExecute to specify the next function to invoke in a series of asynchronous operations.
WS_ASYNC_STATE Used by WsAsyncExecute to manage the state of an asynchronous operation.

 

Asynchronous Function Example

WS_ASYNC_CALLBACK

WS_ASYNC_CONTEXT

WS_CALLBACK_MODEL

WsAsyncExecute