次の方法で共有


ConcurrencyMode 再入

Download sample

このサンプルでは、サービス実装で 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 でないことを確認し、その後コールバック チャネル (この場合は、元の Ping メッセージの送信に使用されたチャネル) の Ping メソッドを呼び出し、チック カウントを 1 だけデクリメントします。チック カウントが 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 サンプルの 1 回限りのセットアップの手順」が実行済みであることを確認します。

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

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

例示

サンプルを実行するには、クライアント プロジェクトとサーバー プロジェクトをビルドします。次に 2 つのコマンド ウィンドウを開き、ディレクトリを <sample>\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

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.