Condividi tramite


Modello asincrono

La maggior parte delle operazioni nell'API servizi Web Windows può essere eseguita in modo sincrono o asincrono. Per chiamare una funzione in modo sincrono, passare un valore Null per la struttura WS_ASYNC_CONTEXT . Per specificare che una funzione può essere eseguita in modo asincrono, passare un WS_ASYNC_CONTEXT non Null alla funzione.

Quando viene chiamato in modo asincrono, una funzione può tuttavia completare in modo sincrono o asincrono. Se la funzione viene completata in modo sincrono, restituisce un valore che indica l'esito positivo o negativo finale e questo valore è sempre diverso da WS_S_ASYNC (vedere Valori restituiti di Servizi Web Windows). Un valore restituito di WS_S_ASYNC indica tuttavia che la funzione verrà completata in modo asincrono. Al termine della funzione in modo asincrono, viene richiamato un callback per segnalare il completamento dell'operazione. Questo callback indica il valore finale di esito positivo o di errore. Il callback non viene chiamato se l'operazione viene completata in modo sincrono.

Per creare un contesto asincrono, inizializzare i campi callback e callbackState della struttura WS_ASYNC_CONTEXT . Il campo callbackState viene utilizzato per specificare un puntatore ai dati definiti dall'utente che vengono passati alla funzione WS_ASYNC_CALLBACK .

Nell'esempio seguente viene illustrata la chiamata asincrona di una funzione passando un puntatore a una struttura WS_ASYNC_CONTEXT che contiene il callback e un puntatore ai dati dello stato.

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 struttura WS_ASYNC_CONTEXT viene usata dalla funzione asincrona solo per la durata della chiamata di funzione (non per la durata dell'operazione asincrona), quindi è possibile dichiararla in modo sicuro nello stack.

Se altri parametri, oltre alla struttura WS_ASYNC_CONTEXT , vengono passati a una funzione asincrona come puntatori e la funzione viene completata in modo asincrono, è responsabilità del chiamante mantenere attivi i valori puntati da questi parametri (non liberati) finché non viene richiamato il callback asincrono.

Esistono limitazioni sulle operazioni che possono essere eseguite da un callback. Per altre informazioni sulle possibili operazioni , vedere il WS_CALLBACK_MODEL.

Quando si implementa una funzione asincrona, non richiamare il callback sullo stesso thread che ha chiamato la funzione asincrona prima che la funzione asincrona sia tornata al chiamante, in quanto ciò interrompe il modello asincrono.

Quando si implementa una funzione che deve eseguire una serie di operazioni asincrone, è consigliabile usare la funzione helper WsAsyncExecute .

L'esempio di funzione asincrona illustra come implementare e utilizzare funzioni che seguono il modello asincrono.

L'avvio di un'operazione di I/O asincrona utilizza le risorse di sistema. Se vengono avviate sufficienti operazioni di I/O, il sistema può non rispondere. Per evitare questo problema, un'applicazione deve limitare il numero di operazioni asincrone che viene avviata.

Il modello asincrono usa gli elementi API seguenti.

Callback Descrizione
WS_ASYNC_CALLBACK Parametro della funzione di callback usato con il modello asincrono.
WS_ASYNC_FUNCTION Usato con WsAsyncExecute per specificare la funzione successiva da richiamare in una serie di operazioni asincrone.

 

Enumerazione Descrizione
WS_CALLBACK_MODEL Specifica il comportamento di threading di un callback, ad esempio un WS_ASYNC_CALLBACK.

 

Funzione Descrizione
WsAsyncExecute Richiama un callback definito dall'utente che può avviare un'operazione asincrona e indicare una funzione che deve essere chiamata al termine dell'operazione asincrona.

 

Struttura Descrizione
WS_ASYNC_CONTEXT Specifica il callback asincrono e un puntatore ai dati definiti dall'utente, che verranno passati al callback asincrono.
WS_ASYNC_OPERATION Usato con WsAsyncExecute per specificare la funzione successiva da richiamare in una serie di operazioni asincrone.
WS_ASYNC_STATE Usato da WsAsyncExecute per gestire lo stato di un'operazione asincrona.

 

Esempio di funzione asincrona

WS_ASYNC_CALLBACK

WS_ASYNC_CONTEXT

WS_CALLBACK_MODEL

WsAsyncExecute