當異步呼叫完成時,伺服器會透過呼叫 rpcAsyncCompleteCall 函式並傳遞異步處理代碼,將回復傳送給客戶端。 即使這個異步呼叫的傳回值是 void,且沒有 [out] 參數,也需要進行此呼叫。 如果函式有傳回值,則會以傳址方式傳遞至 RpcAsyncCompleteCall。
當伺服器呼叫 RpcAsyncCompleteCall 或 RpcAsyncAbortCall,或者當例外狀況在伺服器管理程序中被引發而使呼叫完成時,RPC 執行階段庫會自動終結伺服器的非同步控制碼。
注意
在呼叫 RpcAsyncCompleteCall之前,伺服器必須先完成更新 [in、 out] 和 [out] 參數。 呼叫 rpcAsyncCompleteCall 之後,無法對這些參數或異步句柄進行變更。 如果 RpcAsyncCompleteCall 函數調用失敗,RPC 運行時間會釋放參數。
下列範例示範簡單的異步程序呼叫。
#define DEFAULT_ASYNC_DELAY 20;
#define ASYNC_CANCEL_CHECK 100;
void AsyncFunc(IN PRPC_ASYNC_STATE pAsync,
IN RPC_BINDING_HANDLE hBinding,
IN OUT unsigned long nAsychDelay)
{
int nReply = 1;
RPC_STATUS status;
unsigned long nTmpAsychDelay;
int i;
if (nAsychDelay < 0){
nAsychDelay = DEFAULT_ASYNC_DELAY;
}else if (nAsychDelay < 100){
nAsychDelay = 100;
}
// We only call RpcServerTestCancel if the call
// takes longer than ASYNC_CANCEL_CHECK ms
if(nAsychDelay > ASYNC_CANCEL_CHECK){
nTmpAsychDelay = nAsychDelay/100;
for (i = 0; i < 100; i++){
Sleep(nTmpAsychDelay);
if (i%5 == 0){
fprintf(stderr,
"\rRunning AsyncFunc (%lu ms) (%d%c) ... ",
nAsychDelay, i+5, PERCENT);
status =
RpcServerTestCancel(
RpcAsyncGetCallHandle(pAsync));
if (status == RPC_S_OK){
fprintf(stderr,
"\nAsyncFunc has been canceled!!!\n");
break;
}else if (status != RPC_S_CALL_IN_PROGRESS){
printf(
"RpcAsyncInitializeHandle returned 0x%x\n",
status);
exit(status);
}
}
}
}else{
Sleep(nAsychDelay);
}
printf("\nCalling RpcAsyncCompleteCall\n");
status = RpcAsyncCompleteCall(pAsync, &nReply);
printf("RpcAsyncCompleteCall returned 0x%x\n", status);
if (status){
exit(status);
}
}
為了簡單起見,這個異步伺服器例程不會處理實際數據。 它只是讓自己睡了一下。
注意
RpcAsyncCompleteCall 函式可以在接收呼叫的線程上或進程中的任何其他線程上呼叫。 如果完成呼叫所需的所有數據都可供使用,伺服器可能會在同一個線程上填入,並在相同的線程上呼叫 RpcAsyncCompleteCall。 藉由此方法,可以節省一些內容切換並改善效能。 這類呼叫會以機會的異步方式進行。
相關主題