次の方法で共有


ConcurrencyMode 再入

Reentrant サンプルは、サービス実装で ConcurrencyMode.Reentrant を使用することの必要性と影響を示しています。 ConcurrencyMode.Reentrant は、サービス (またはコールバック) が特定の時点で 1 つのメッセージのみを処理することを意味します ( ConcurencyMode.Singleに似ています)。 スレッド セーフを確保するために、Windows Communication Foundation (WCF) は、メッセージを処理する InstanceContext をロックして、他のメッセージを処理できないようにします。 再入モードの場合、InstanceContext はサービスが発信呼び出しを行う直前にロックが解除されるため、後続の呼び出しが次回サービスに入る際にロックを取得できるようになります(サンプルで示されているように、再入可能です)。 この動作を示すために、このサンプルでは、クライアントとサービスが双方向コントラクトを使用して相互にメッセージを送信する方法を示します。

定義されているコントラクトは、サービスによって実装されている Ping メソッドと、クライアントによって実装されているコールバック メソッド Pong 双方向コントラクトです。 クライアントは、サーバーの Ping メソッドをティックカウントで呼び出し、それによって呼び出しを開始します。 このサービスは、ティック数が 0 に等しくないかどうかをチェックし、ティック数を減らしながら、メソッド Pong コールバックを呼び出します。 これは、サンプルの次のコードによって行われます。

public void Ping(int ticks)
{
     Console.WriteLine("Ping: Ticks = " + ticks);
     //Keep pinging back and forth till Ticks reaches 0.
     if (ticks != 0)
     {
         OperationContext.Current.GetCallbackChannel<IPingPongCallback>().Pong((ticks - 1));
     }
}

コールバックの Pong 実装には、 Ping 実装と同じロジックがあります。 つまり、ティック数が 0 ではないかどうかをチェックし、ティック数を 1 減らしてからコールバック チャネルで Ping メソッドを呼び出します(この場合、元の Ping メッセージの送信に使用されたチャネルです)。 チック カウントが 0 になると、このメソッドは返されます。これによってすべての応答のラップが解除され、クライアントが呼び出して初期化した最初の呼び出しに戻されます。 これはコールバック実装に示されています。

public void Pong(int ticks)
{
    Console.WriteLine("Pong: Ticks = " + ticks);
    if (ticks != 0)
    {
        //Retrieve the Callback  Channel (in this case the Channel which was used to send the
        //original message) and make an outgoing call until ticks reaches 0.
        IPingPong channel = OperationContext.Current.GetCallbackChannel<IPingPong>();
        channel.Ping((ticks - 1));
    }
}

PingメソッドとPong メソッドはどちらも要求/応答です。つまり、Pingの最初の呼び出しは、CallbackChannel<T>.Pong()の呼び出しが返されるまで戻りません。 クライアントでは、 Pong メソッドは、次の Ping 呼び出しが返されるまで戻ることができません。 コールバックとサービスの両方が保留中の要求に対して応答する前に送信要求/応答呼び出しを行う必要があるため、両方の実装に ConcurrencyMode.Reentrant 動作のマークを付ける必要があります。

サンプルを設定、ビルド、実行するには

  1. Windows Communication Foundation サンプル One-Time セットアップ手順を実行していることを確認します。

  2. ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。

  3. 単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。

対象

サンプルを実行するには、クライアント プロジェクトとサーバー プロジェクトをビルドします。 次に、2 つのコマンド ウィンドウを開き、ディレクトリを <ample>\CS\Service\bin\debug と <sample>\CS\Client\bin\debug ディレクトリに変更します。 次に、「 service.exe 」と入力してサービスを開始し、入力引数として渡されたティックの初期値を使用して Client.exe を呼び出します。 サンプルでは、チックとして 10 が出力されます。

Prompt>Service.exe
ServiceHost Started. Press Enter to terminate service.
Ping: Ticks = 10
Ping: Ticks = 8
Ping: Ticks = 6
Ping: Ticks = 4
Ping: Ticks = 2
Ping: Ticks = 0

Prompt>Client.exe 10
Pong: Ticks = 9
Pong: Ticks = 7
Pong: Ticks = 5
Pong: Ticks = 3
Pong: Ticks = 1