共用方式為


進行異步呼叫

在執行非同步遠端呼叫之前,客戶端必須先初始化非同步句柄。 客戶端和伺服器程式使用指向 RPC_ASYNC_STATE 結構的指標來處理異步句柄。

每個待處理的呼叫都必須有其獨特的非同步控制代碼。 用戶端會建立句柄,並將其傳遞至 rpcAsyncInitializeHandle函式。 若要讓呼叫正確完成,客戶端必須確定在收到伺服器的異步回復之前,不會釋放句柄的記憶體。 此外,在對現有異步句柄進行另一個呼叫之前,客戶端必須重新初始化句柄。 若無法這麼做,可能會導致用戶端存根在呼叫期間引發例外狀況。 用戶端必須確保它提供給 [輸出] 參數及 [輸入輸出] 參數的緩衝區在異步遠端程式的過程中保持分配,直到收到來自伺服器的回覆為止。

當它叫用異步遠端程式時,客戶端必須選取 RPC 執行時間連結庫將用來通知呼叫完成的方法。 用戶端可以透過下列任一方式接收此通知:

  • 事件。 客戶可以指定一個事件,以在呼叫完成時觸發。 如需詳細資訊,請參閱 事件物件

  • 投票。 用戶端可以重複呼叫 rpcAsyncGetCallStatus 。 如果傳回值不是RPC_S_ASYNC_CALL_PENDING,呼叫就會完成。 這個方法使用的 CPU 時間比這裡所述的其他方法還多。

  • APC。 用戶端可以指定 異步過程調用 (APC) 呼叫完成時呼叫。 如需 APC 函式的原型,請參閱 RPCNOTIFICATION_ROUTINE。 呼叫 APC 時,其 Event 參數設定為 RpcCallComplete。 若要讓 APC 分派,用戶端執行緒必須處於警覺等待狀態。

    如果異步句柄中的 [hThread] 字段設定為 0,則 APC 會在進行異步呼叫的線程上排入佇列。 如果非零,則 APC 會在 m 指定的線程上排入佇列。

  • 國際奧會。 I/O 完成埠會收到在非同步句柄中指定的參數的通知。 如需詳細資訊,請參閱 CreateIoCompletionPort

  • Windows 句柄。 訊息會張貼至指定的視窗控制代碼 (HWND)。

下列代碼段顯示初始化異步句柄及使用它進行異步遠程過程調用所需的基本步驟。

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

如此範例所示,您的用戶端程式可以在非同步程序呼叫仍未完成時執行同步遠端程序呼叫。 此用戶端會為 RPC 執行時間連結庫建立事件物件,以在異步呼叫完成時用來通知它。

注意

如果在異步呼叫期間引發 RPC 例外狀況,則不會從異步 RPC 例程傳回完成通知。