このトピックでは、コンテキスト ハンドルのエラー セマンティクスについて説明します。
コンテキスト ハンドルを閉じるときに失敗するセマンティクスが失敗する
クライアント アプリケーションが、クライアント プロセスをシャットダウンせずに、サーバー上で開かれたコンテキスト ハンドルを閉じようとしているとします。 また、コンテキスト ハンドルを閉じるサーバーへの呼び出しが失敗したとします (たとえば、クライアントがメモリ不足です)。 この状況を適切に処理するには、RpcSsDestroyClientContext 関数を呼び出します。 このような場合、クライアントはコンテキスト ハンドルの側をクリーンアップし、サーバーへの接続を中止して閉じます。 接続は実際には接続プールであるため (RPC とネットワークを参照)、開かれたバインドまたはコンテキスト ハンドルごとに 1 つの参照でカウントされます。RpcSsDestroyClientContext 関数 呼び出してコンテキスト ハンドルを破棄しても、実際には接続は破棄されません。 代わりに、接続プールの参照カウントがデクリメントされます。 プール内の接続を閉じるには、クライアント プロセスからそのサーバーに対するすべてのバインド ハンドルとコンテキスト ハンドルを閉じる必要があります。 その後、プール内のすべての接続が閉じられ、サーバーのランダウン メカニズムが開始され、クリーンアップされます。
コンテキスト ハンドルの状態の変更中のエラー セマンティクス
このセクションの情報では、Windows XP 以降のプラットフォームについて説明します。
コンテキスト ハンドルは、単に関数のパラメーターです。 コンテキスト ハンドルの状態のすべての変更は、パラメーターがマーシャリングまたはマーシャリング解除されるときに発生します。 たとえば、クライアントがコンテキスト ハンドルを開いた場合 (NULL から非NULLに変更)、RPC ランタイムは、クライアントに送信するために引数がマーシャリングされるまで、実際にはハンドルの RPC 部分を開きません。 エラーは、中間中に発生する可能性があります。 さまざまなネットワークまたはリソースの不足状態により、クライアントへのパケットの送信が失敗する可能性があります。 または、サーバー ルーチンは、コンテキスト ハンドルの変更中に例外をスローする可能性があります。 このような状況やその他の障害状況では、クライアントとサーバーがコンテキスト ハンドルの一貫性のないビューを取得する可能性があります。 このセクションでは、コンテキスト ハンドルの状態に関する規則と、さまざまな障害状態でのクライアントコードとサーバー コードの責任について説明します。
NULL コンテキスト ハンドルが到着しますが、サーバー ルーチンでエラーが発生し、例外がスローされます。
作成したコンテキスト ハンドル関連の状態をクリーンアップするのは、サーバー ルーチンの役割です。 RPC ランタイムは、その状態をクリーンアップします。
以外の NULL コンテキスト ハンドルが到着しますが、サーバー ルーチンでエラーが発生し、例外がスローされます。
サーバー ルーチンがコンテキスト ハンドルを閉じた場合、クライアントはコンテキスト ハンドルを認識しません。呼び出しは成功しないためです。コンテキスト ハンドルをさらに使用すると、クライアントでRPC_X_SS_CONTEXT_MISMATCH エラーが発生します。 サーバー ルーチンがコンテキスト ハンドルを変更しない場合でも、クライアントはコンテキスト ハンドルを使用できます。 サーバー ルーチンがサーバー コンテキストに格納されている情報を変更すると、クライアントからの新しい呼び出しでその情報が使用されます。
非NULL コンテキスト ハンドルが到着し、サーバー ルーチンはハンドルを閉じますが、コンテキスト ハンドルがマーシャリングされた後のマーシャリングは失敗するか、マーシャリングが失敗した後の処理のいずれかになります。
コンテキスト ハンドルが閉じられ、このコンテキスト ハンドルを使用してこのクライアントによってさらに呼び出されると、クライアントでRPC_X_SS_CONTEXT_MISMATCH エラーが発生します。
NULL コンテキスト ハンドルが到着すると、サーバーはこのハンドルのコンテキストを作成しますが、コンテキスト ハンドルがマーシャリングされた後のマーシャリングは失敗するか、マーシャリングが失敗した後の処理になります。
この場合、RPC ランタイムは、このコンテキスト ハンドルの実行を呼び出し、このコンテキスト ハンドルの RPC 状態をクリーンアップします。 コンテキスト ハンドルは、クライアント側では作成されません。
非NULL コンテキスト ハンドルが到着し、サーバーはコンテキスト ハンドルを変更しないか、サーバー コンテキストに格納されている情報を変更します。また、コンテキスト ハンドルがマーシャリングされた後にマーシャリングが失敗します。
クライアントからの新しい呼び出しでは、サーバーが持つコンテキスト ハンドルが使用されます。
NULL コンテキスト ハンドルが到着し、サーバーは NULL 以外に設定しませんが、コンテキスト ハンドルがマーシャリングされる前に呼び出しが失敗します。
この場合、クライアントにコンテキスト ハンドルは作成されません。
非NULL コンテキスト ハンドルが到着し、サーバーによって NULL 設定されますが、コンテキスト ハンドルがマーシャリングされる前にマーシャリングが失敗します。
この場合、コンテキスト ハンドルはサーバー上で閉じたままになり、クライアントはコンテキスト ハンドルを使用しようとしたときにRPC_X_SS_CONTEXT_MISMATCHエラーを受け取ります。
NULL コンテキスト ハンドルがサーバーに到着し、サーバーによって非NULLに設定されますが、コンテキスト ハンドルがマーシャリングされる前にマーシャリングが失敗します。
コンテキスト ハンドルの実行は、サーバーがクリーンアップできるように呼び出され、クライアントにコンテキスト ハンドルが作成されません。
非NULL コンテキスト ハンドルが到着し、サーバーはコンテキスト ハンドルを変更しないか、サーバー コンテキストに格納されている情報を変更します。また、コンテキスト ハンドルがマーシャリングされる前にマーシャリングが失敗します。
クライアントからの新しい呼び出しでは、サーバー上の状態が使用されます。
コンテキスト ハンドルは戻り値として宣言され、サーバー ルーチンはコンテキスト ハンドル NULL を返します。マーシャリングは、コンテキスト ハンドルがマーシャリングされる前に失敗します。
この場合、クライアントに新しいコンテキストは作成されません。
コンテキスト ハンドルは戻り値として宣言され、サーバー ルーチンはコンテキスト ハンドルの非NULL を返します。マーシャリングは、コンテキスト ハンドルがマーシャリングされる前に失敗します。
RPC ランタイムは、コンテキスト ハンドルランダウン ルーチンを呼び出してクリーンアップする機会を与え、クライアントに新しいコンテキストは作成されません。