Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Ketika panggilan asinkron selesai, server mengirimkan balasan kepada klien dengan memanggil fungsi RpcAsyncCompleteCall dan meneruskannya handle asinkronnya. Panggilan ini diperlukan bahkan jika panggilan asinkron memiliki nilai pengembalian yang batal dan tidak ada parameter [keluar]. Jika fungsi memiliki nilai pengembalian, fungsi tersebut diteruskan dengan referensi ke RpcAsyncCompleteCall.
Ketika server memanggil RpcAsyncCompleteCall atau RpcAsyncAbortCall, atau panggilan selesai karena pengecualian terjadi dalam rutinitas manajer server, pustaka run-time RPC secara otomatis menghancurkan handle asinkron server.
Nota
Server harus selesai memperbarui parameter [in, out] dan [out] sebelum memanggil RpcAsyncCompleteCall. Tidak ada perubahan yang dapat dilakukan pada parameter tersebut atau ke handle asinkron setelah memanggil RpcAsyncCompleteCall. Jika panggilan fungsi RpcAsyncCompleteCall gagal, runtime RPC membebaskan parameter.
Contoh berikut menunjukkan panggilan prosedur asinkron sederhana.
#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);
}
}
Demi kesederhanaan, rutinitas server asinkron ini tidak memproses data aktual. Itu hanya menempatkan dirinya untuk tidur untuk sementara waktu.
Nota
Fungsi RpcAsyncCompleteCall dapat dipanggil baik pada utas yang menerima panggilan, atau pada utas lain dalam proses. Jika semua data yang diperlukan untuk menyelesaikan panggilan tersedia dengan mudah, server dapat mengisi data tersebut di benang yang sama, dan memanggil RpcAsyncCompleteCall pada benang yang sama. Pendekatan ini menghemat beberapa pengalihan konteks dan meningkatkan performa. Panggilan seperti itu disebut opportunistik asinkron.
Topik terkait