Eşzamansız Yanıt Bekleniyor
İstemcinin sunucudan bir yanıt bildirilmesini beklerken ne yaptığı, seçtiği bildirim mekanizmasına bağlıdır.
İstemci bildirim için bir olay kullanırsa, genellikle WaitForSingleObject işlevini veya WaitForSingleObjectEx işlevini çağırır. İstemci, bu işlevlerden birini çağırdığında engellenmiş bir duruma girer. İstemci engellendiğinde CPU çalışma döngülerini kullanmadığı için bu verimlidir.
Sonuçları beklemek için yoklama kullandığında, istemci programı, RpcAsyncGetCallStatusişlevini tekrar tekrar çağıran bir döngüye girer. Bu, istemci programınız yoklama döngüsünde başka işlemler yaparsa beklemenin verimli bir yöntemidir. Örneğin, sonraki bir zaman uyumsuz uzak yordam çağrısı için küçük öbekler halinde veri hazırlayabilir. Her öbek tamamlandıktan sonra, istemciniz tamam olup olmadığını görmek için bekleyen zaman uyumsuz uzak yordam çağrısını yoklayabilir.
İstemci programınız, eşzamansız uzak yordam çağrısı tamamlandığında RPC çalışma zamanı kütüphanesinin çağıracağı bir geri çağırma işlevi türü olan eşzamansız bir yordam çağrısı (APC) sağlayabilir. İstemci programınız uyarılabilen bir bekleme durumunda olmalıdır. Bu genellikle istemcinin kendisini engellenmiş duruma getirmek için bir Windows API işlevi çağırdığını gösterir. Daha fazla bilgi için bkz. Zaman Uyumsuz Yordam Çağrıları.
Not (when contextually appropriate, alternative translations could include "Dikkat", "Açıklama", or "Not Alın" if they fit better within a given sentence or context)
Zaman uyumsuz bir çağrı sırasında bir RPC özel durumu tetiklenirse, zaman uyumsuz rpc yordamından tamamlanma bildirimi döndürülmeyecektir.
İstemci programınız tamamlama bildirimini almak için G/Ç tamamlama bağlantı noktası kullanıyorsa getQueuedCompletionStatusişleviniçağırmalıdır. Bu olduğunda, yanıt için sınırsız süre bekleyebilir veya başka işlemler yapmaya devam edebilir. Yanıt beklerken başka işlemler de yaparsa, GetQueuedCompletionStatus işleviyle tamamlama portunu yoklaması gerekir. Bu durumda, genellikle dwMilliseconds sıfır olarak ayarlaması gerekir. Bu, zaman uyumsuz çağrı tamamlanmamış olsa bile GetQueuedCompletionStatus'in hemen dönmesine neden olur.
İstemci programları, pencere ileti kuyrukları aracılığıyla tamamlama bildirimi de alabilir. Bu durumda, tamamlama iletisini herhangi bir Windows iletisi gibi işler.
Bir istemci, ancak çağrıyı başlatan iş parçacığı çağrıdan başarıyla döndükten sonra, zaman uyumsuz bir çağrıyı iptal edebilir; bu durum, çok iş parçacıklı bir uygulamada geçerlidir. Bu, eşzamanlı bir çağrı başarısız olduktan sonra çağrının başka bir iş parçacığı tarafından eşzamansız bir şekilde iptal edilmemesini sağlar. Standart uygulama olarak, zaman uyumlu olarak başarısız olan zaman uyumsuz bir çağrı zaman uyumsuz olarak iptal edilmemelidir. Çağrılar farklı iş parçacıklarında verilebilir ve iptal edilebilirse istemci uygulaması bu davranışı izlemelidir. Ayrıca, çağrı iptal edildikten sonra istemci kodunun tamamlanma bildirimini beklemesi ve aramayı tamamlaması gerekir. RpcAsyncCancelCall işlevi yalnızca tamamlanma bildirimini aceleye getirerek; çağrıyı tamamlamanın yerini tutmaz.
Aşağıdaki kod parçası, bir istemci programının zaman uyumsuz yanıt beklemek için bir olayı nasıl kullanabileceğini gösterir.
// This code fragment assumes that Async is a valid asynchronous
// RPC handle.
if (WaitForSingleObject(Async.u.hEvent, INFINITE) == WAIT_FAILED)
{
RpcRaiseException(APP_ERROR);
}
Asenkron bir yanıt bildirimi almak için APC kullanan istemci programları genellikle kendilerini engelli duruma geçirir. Aşağıdaki kod parçası bunu gösterir.
if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION)
{
RpcRaiseException(APP_ERROR);
}
Bu durumda istemci programı uyku moduna geçer ve RPC çalışma zamanı kitaplığı APC'yi çağırana kadar (gösterilmez) CPU döngüleri kullanmaz.
Sonraki örnek, asenkron yanıt beklemek için bir G/Ç tamamlama bağlantı noktası kullanan bir istemciyi göstermektedir.
// This code fragment assumes that Async is a valid asynchronous
// RPC handle.
if (!GetQueuedCompletionStatus(
Async.u.IOC.hIOPort,
&Async.u.IOC.dwNumberOfBytesTransferred,
&Async.u.IOC.dwCompletionKey,
&Async.u.IOC.lpOverlapped,
INFINITE))
{
RpcRaiseException(APP_ERROR);
}
Yukarıdaki örnekte GetQueuedCompletionStatusçağrısı, zaman uyumsuz uzak yordam çağrısı tamamlanana kadar süresiz olarak bekler.
Çok iş parçacıklı uygulamalar yazarken potansiyel bir tuzağa düşülebilir. Bir iş parçacığı uzak bir yordam çağrısı gerçekleştirir ve ardından gönderimin tamamlandığına dair bildirim almadan önce sonlandırılırsa, uzak yordam çağrısı başarısız olabilir ve istemci stub'u sunucuya olan bağlantısını kapatabilir. Bu nedenle, uzak yordam çağıran iş parçacıkları, davranış istenmeyen olduğunda çağrı tamamlanmadan veya iptal edilmeden önce sonlandırılmamalıdır.