Compartir a través de


Modelo asincrónico

La mayoría de las operaciones de la API de servicios web de Windows se pueden realizar de forma sincrónica o asincrónica. Para llamar a una función de forma sincrónica, pase un valor NULL para la estructura de WS_ASYNC_CONTEXT . Para especificar que una función se puede realizar de forma asincrónica, pase un WS_ASYNC_CONTEXT distinto de NULL a la función.

Cuando se llama de forma asincrónica, una función puede completarse de forma sincrónica o asincrónica. Si la función se completa de forma sincrónica, devuelve un valor que indica el error o el éxito final, y este valor siempre es algo distinto de WS_S_ASYNC (vea Valores devueltos de servicios web de Windows). Sin embargo, un valor devuelto de WS_S_ASYNC indica que la función se completará de forma asincrónica. Cuando la función se completa de forma asincrónica, se invoca una devolución de llamada para indicar la finalización de la operación. Esta devolución de llamada indica el valor final correcto o de error. No se llama a la devolución de llamada si la operación se completa de forma sincrónica.

Para crear un contexto asincrónico, inicialice los campos callback y callbackState de la estructura WS_ASYNC_CONTEXT . El campo callbackState se usa para especificar un puntero a los datos definidos por el usuario que se pasan a la función WS_ASYNC_CALLBACK .

En el ejemplo siguiente se muestra cómo llamar a una función de forma asincrónica pasando un puntero a una estructura de WS_ASYNC_CONTEXT que contiene la devolución de llamada y un puntero a los datos de estado.

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

La función asincrónica usa la estructura WS_ASYNC_CONTEXT solo durante la llamada de función (no durante la operación asincrónica), por lo que puede declararla de forma segura en la pila.

Si cualquier otro parámetro, además de la estructura de WS_ASYNC_CONTEXT , se pasa a una función asincrónica como punteros y la función se completa de forma asincrónica, es responsabilidad del autor de la llamada mantener activos los valores señalados por estos parámetros (no liberados) hasta que se invoque la devolución de llamada asincrónica.

Hay limitaciones en las operaciones que puede realizar una devolución de llamada. Para obtener más información sobre las posibles operaciones , consulte la WS_CALLBACK_MODEL.

Al implementar una función asincrónica, no invoque la devolución de llamada en el mismo subproceso que llamó a la función asincrónica antes de que la función asincrónica haya vuelto al autor de la llamada, ya que esto interrumpe el modelo asincrónico.

Al implementar una función que necesita ejecutar una serie de operaciones asincrónicas, considere la posibilidad de usar la función auxiliar WsAsyncExecute .

En el ejemplo de función asincrónica se muestra cómo implementar y consumir funciones que siguen el modelo asincrónico.

Iniciar una operación de E/S asincrónica consume recursos del sistema. Si se inician suficientes operaciones de E/S, el sistema puede dejar de responder. Para evitar esto, una aplicación debe limitar el número de operaciones asincrónicas que se inician.

El modelo asincrónico usa los siguientes elementos de API.

Devolución de llamada Descripción
WS_ASYNC_CALLBACK Parámetro de función de devolución de llamada usado con el modelo asincrónico.
WS_ASYNC_FUNCTION Se usa con WsAsyncExecute para especificar la siguiente función que se va a invocar en una serie de operaciones asincrónicas.

 

Enumeración Descripción
WS_CALLBACK_MODEL Especifica el comportamiento de subprocesos de una devolución de llamada (por ejemplo, un WS_ASYNC_CALLBACK).

 

Función Descripción
WsAsyncExecute Invoca una devolución de llamada definida por el usuario que puede iniciar una operación asincrónica e indicar una función a la que se debe llamar cuando se ha completado la operación asincrónica.

 

Estructura Descripción
WS_ASYNC_CONTEXT Especifica la devolución de llamada asincrónica y un puntero a los datos definidos por el usuario, que se pasarán a la devolución de llamada asincrónica.
WS_ASYNC_OPERATION Se usa con WsAsyncExecute para especificar la siguiente función que se va a invocar en una serie de operaciones asincrónicas.
WS_ASYNC_STATE Usado por WsAsyncExecute para administrar el estado de una operación asincrónica.

 

Ejemplo de función asincrónica

WS_ASYNC_CALLBACK

WS_ASYNC_CONTEXT

WS_CALLBACK_MODEL

WsAsyncExecute