Win32 RPC 編程(三) 示例下載編程
咱們在上一節的基礎上,討論如何實現異步的 RPC 調用。前兩節演示的函數調用都是同步的,即調用函數 Hello() 時,客戶端將阻塞住直到服務端的 Hello() 函數返回。若是服務端函數須要進行一些費時的操做,例如複雜的計算、查詢,客戶端只能一直阻塞在那裏。這種狀況下,咱們能夠使用異步的 RPC 提升客戶端的性能。異步
異步的RPC是經過配置文件(.acf)來啓用的:async
原來的接口 HelloWorld 有兩個方法,Hello() 和 Shutdown(),Shutdown() 咱們仍然讓它是同步調用,因此在.acf文件中不用列出。IDL 接口文件仍是能夠不用修改。ide
服務端的代碼 server.c 中的 Hello() 要改爲下面的樣子:函數
Cpp代碼性能
- void Hello(PRPC_ASYNC_STATE rpcAsyncHandle, const unsigned char * psz)
- {
-
- printf("Sleep 5 seconds...\n");
- Sleep(5000);
- printf("%s\n", psz);
-
-
- RpcAsyncCompleteCall(rpcAsyncHandle, NULL);
- }
void Hello(PRPC_ASYNC_STATE rpcAsyncHandle, const unsigned char * psz)
{
// 模擬一個長時間的操做
printf("Sleep 5 seconds...\n");
Sleep(5000);
printf("%s\n", psz);
// 代表調用已經完成
RpcAsyncCompleteCall(rpcAsyncHandle, NULL);
}
服務端的其它代碼不用修改。spa
客戶端client.c中的調用方式也要換:code
Cpp代碼server
- int main(int argc, char * argv[])
- {
-
- ...
-
-
- RpcTryExcept
- {
-
- if ( _stricmp(argv[1], "SHUTDOWN") == 0 )
- {
- Shutdown();
- }
- else
- {
-
- RPC_ASYNC_STATE async;
- RpcAsyncInitializeHandle( &async, sizeof(async) );
- async.UserInfo = NULL;
- async.NotificationType = RpcNotificationTypeNone;
-
-
- Hello( &async, (unsigned char*)argv[1]);
-
-
- while ( RpcAsyncGetCallStatus(&async) == RPC_S_ASYNC_CALL_PENDING )
- {
- printf("Call Hello() pending, wait 1s...\n");
- Sleep(1000);
- }
-
-
- RpcAsyncCompleteCall( &async, NULL );
- }
- }
- RpcExcept(1)
- {
- printf( "RPC Exception %d\n", RpcExceptionCode() );
- }
- RpcEndExcept
-
-
-
- ...
- }
- Hello.acf:
- [
- implicit_handle(handle_t HelloWorld_Binding)
- ]
-
- interface HelloWorld
- {
- [async] Hello();
- }
Hello.acf:
[
implicit_handle(handle_t HelloWorld_Binding)
]
interface HelloWorld
{
[async] Hello(); // 增長了 [async] 代表這是異步調用
}