Creazione 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 avere un proprio handle asincrono univoco. Il client crea l'handle e lo passa alla funzione RpcAsyncInitializeHandle . Per completare correttamente la chiamata, 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. Questa operazione può causare l'aumento di un'eccezione da parte del client durante la chiamata. Il client deve inoltre assicurarsi che i buffer forniti per i parametri [out] e i parametri [in, out] a una routine remota asincrona rimangano allocati fino a quando non ha ricevuto la risposta dal server.
Quando richiama una routine remota asincrona, il client deve selezionare il metodo 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, vedere Oggetti evento.
Polling. 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 di CPU rispetto agli altri metodi descritti qui.
APC. Il client può specificare una chiamata di routine asincrona (APC) che viene chiamata al completamento della chiamata. Per il prototipo della funzione APC, vedere RPCNOTIFICATION_ROUTINE. Il servizio APC viene chiamato con il parametro Event impostato su RpcCallComplete. Per l'invio delle API, il thread client deve trovarsi in uno stato di attesa avvisabile.
Se il campo hThread nell'handle asincrono è impostato su 0, le API vengono accodate nel thread che ha effettuato la chiamata asincrona. Se è diverso da zero, le API vengono accodate nel thread specificato da m.
IOC. La porta di completamento di I/O viene notificata con i parametri specificati nell'handle asincrono. Per altre informazioni, vedere CreateIoCompletionPort.
Handle di Windows. Viene inviato un messaggio all'handle di finestra specificato (HWND).
Il frammento di codice seguente illustra i passaggi essenziali necessari per inizializzare un handle asincrono e usarlo per eseguire una chiamata di routine remota asincrona.
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 remote sincrone mentre una chiamata di routine asincrona è ancora in sospeso. Questo client crea un oggetto evento per la libreria di runtime RPC da usare per notificarlo al completamento della chiamata asincrona.
Nota
La notifica del completamento non verrà restituita da una routine RPC asincrona se viene generata un'eccezione RPC durante una chiamata asincrona.