Condividi tramite


Esecuzione della chiamata asincrona

Prima di poter effettuare una chiamata remota asincrona, il client deve inizializzare l'handle asincrono. I programmi client e server usano puntatori alla struttura RPC_ASYNC_STATE per gli handle asincroni.

Ogni chiamata in sospeso deve disporre di un handle asincrono univoco. Il client crea l'handle e lo passa alla funzione RpcAsyncInitializeHandle. Affinché la chiamata venga completata correttamente, il client deve assicurarsi che la memoria per l'handle non venga rilasciata finché non riceve la risposta asincrona del server. Inoltre, prima di effettuare un'altra chiamata su un handle asincrono esistente, il client deve reinizializzare l'handle. La mancata esecuzione di questa operazione può causare allo stub del client di generare un'eccezione durante la chiamata. Il client deve anche assicurarsi che i buffer forniti per i parametri [out] e [in, out] parametri in una routine remota asincrona rimangono allocati fino a quando non ha ricevuto la risposta dal server.

Quando richiama una procedura remota asincrona, il client deve selezionare il metodo che verrà usato dalla libreria di runtime RPC per notificare il completamento della chiamata. Il client può ricevere questa notifica in uno dei modi seguenti:

  • Evento. Il client può specificare un evento da attivare al termine della chiamata. Per informazioni dettagliate, consultare Oggetti Evento.

  • Sondaggio Il client può chiamare ripetutamente RpcAsyncGetCallStatus. Se il valore restituito è diverso da RPC_S_ASYNC_CALL_PENDING, la chiamata viene completata. Questo metodo usa più tempo cpu rispetto agli altri metodi descritti qui.

  • APC. Il client può specificare una chiamata di routine asincrona (APC) che viene chiamata al termine della chiamata. Per il prototipo della funzione APC, vedere RPCNOTIFICATION_ROUTINE. L'APC viene chiamato con il relativo parametro Event impostato su RpcCallComplete. Affinché gli APC possano venire invocati, il thread client deve trovarsi in uno stato di attesa allertabile.

    Se il campo hThread nell'handle asincrono è impostato su 0, gli APC vengono accodati sul thread che ha effettuato la chiamata asincrona. Se è diverso da zero, gli APC vengono accodati sul thread specificato da m.

  • IOC. La porta di completamento I/O riceve una notifica con i parametri specificati nell'handle asincrono. Per altre informazioni, vedere CreateIoCompletionPort.

  • Maniglia di Windows Viene inviato un messaggio all'handle della finestra specificata (HWND).

Il frammento di codice seguente illustra i passaggi essenziali necessari per inizializzare un handle asincrono e usarlo per effettuare una chiamata asincrona di procedura remota.

RPC_ASYNC_STATE Async;
RPC_STATUS status;
 
// Initialize the handle.
status = RpcAsyncInitializeHandle(&Async, sizeof(RPC_ASYNC_STATE));
if (status)
{
    // Code to handle the error goes here.
}
 
Async.UserInfo = NULL;
Async.NotificationType = RpcNotificationTypeEvent;
 
Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (Async.u.hEvent == 0)
{
    // Code to handle the error goes here.
}
// Call an asynchronous RPC routine here
RpcTryExcept
{
    printf("\nCalling the remote procedure 'AsyncFunc'\n");
    AsyncFunc(&Async, AsyncRPC_ClientIfHandle, nAsychDelay);
}
RpcExcept(1)
{
    ulCode = RpcExceptionCode();
    printf("AsyncFunc: Run time reported exception 0x%lx = %ld\n", 
            ulCode, ulCode);
}
RpcEndExcept
 
// Call a synchronous routine while
// the asynchronous procedure is still running
RpcTryExcept
{
    printf("\nCalling the remote procedure 'NonAsyncFunc'\n");
    NonAsyncFunc(AsyncRPC_ClientIfHandle, pszMessage);
    fprintf(stderr, 
            "While 'AsyncFunc' is running asynchronously,\n"
            "we still can send message to the server in the mean "
            "time.\n\n");
}
RpcExcept(1)
{
    ulCode = RpcExceptionCode();
    printf("NonAsyncFunc: Run time reported exception 0x%lx = %ld\n", 
            ulCode, ulCode);
}
RpcEndExcept

Come illustrato in questo esempio, il programma client può eseguire chiamate di routine remota sincrone mentre è ancora in sospeso una chiamata di procedura asincrona. Questo client crea un oggetto evento per la libreria di runtime RPC da usare per notificarlo al completamento della chiamata asincrona.

Nota

La notifica di completamento non verrà restituita da una routine RPC asincrona se viene generata un'eccezione RPC durante una chiamata asincrona.