コンカレンシー サンプルでは、ConcurrencyMode列挙体でServiceBehaviorAttributeを使用する方法を示します。この列挙は、サービスのインスタンスがメッセージを順番に処理するか、同時に処理するかを制御します。 このサンプルは、 サービス コントラクトを実装するICalculator
に基づいています。 このサンプルでは、ICalculator
から継承する新しいコントラクト ICalculatorConcurrency
を定義し、サービスコンカレンシーの状態を検査するための 2 つの追加操作を提供します。 コンカレンシー設定を変更することで、クライアントを実行することで動作の変化を観察できます。
このサンプルでは、クライアントはコンソール アプリケーション (.exe) であり、サービスはインターネット インフォメーション サービス (IIS) によってホストされています。
注
このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。
使用できるコンカレンシー モードは 3 つあります。
Single
: 各サービス インスタンスは、一度に 1 つのメッセージを処理します。 これは既定のコンカレンシー モードです。Multiple
: 各サービス インスタンスは、複数のメッセージを同時に処理します。 このコンカレンシー モードを使用するには、サービスの実装がスレッド セーフである必要があります。Reentrant
: 各サービス インスタンスは一度に 1 つのメッセージを処理しますが、再入可能な呼び出しを受け入れます。 サービスは、呼び出し時にのみこれらの呼び出しを受け入れます。再入は、 ConcurrencyMode.Reentrant サンプルで示されています。
コンカレンシーの使用は、インスタンス化モードに関連します。 PerCallインスタンス化では、各メッセージは新しいサービス インスタンスによって処理されるため、コンカレンシーは関係ありません。 Singleインスタンス化では、単一インスタンスがメッセージを順番に処理するか同時に処理するかに応じて、SingleまたはMultipleコンカレンシーが関連します。 PerSessionインスタンス化では、コンカレンシー モードのいずれかが関連している可能性があります。
サービス クラスは、次のコード サンプルに示すように、 [ServiceBehavior(ConcurrencyMode=<setting>)]
属性を使用してコンカレンシー動作を指定します。 コメント アウトする行を変更することで、 Single
と Multiple
コンカレンシー モードを試すことができます。 コンカレンシー モードを変更した後は、サービスをリビルドすることを忘れないでください。
// Single allows a single message to be processed sequentially by each service instance.
//[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
// Multiple allows concurrent processing of multiple messages by a service instance.
// The service implementation should be thread-safe. This can be used to increase throughput.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
// Uses Thread.Sleep to vary the execution time of each operation.
public class CalculatorService : ICalculatorConcurrency
{
int operationCount;
public double Add(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(180);
return n1 + n2;
}
public double Subtract(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(100);
return n1 - n2;
}
public double Multiply(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(150);
return n1 * n2;
}
public double Divide(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(120);
return n1 / n2;
}
public string GetConcurrencyMode()
{
// Return the ConcurrencyMode of the service.
ServiceHost host = (ServiceHost)OperationContext.Current.Host;
ServiceBehaviorAttribute behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
return behavior.ConcurrencyMode.ToString();
}
public int GetOperationCount()
{
// Return the number of operations.
return operationCount;
}
}
このサンプルでは、既定でSingleインスタンス化でMultipleコンカレンシーを使用します。 非同期プロキシを使用するようにクライアント コードが変更されました。 これにより、クライアントは、各呼び出し間の応答を待たずに、サービスに対して複数の呼び出しを行うことができます。 サービス コンカレンシー モードの動作の違いを確認できます。
サンプルを実行すると、操作要求と応答がクライアント コンソール ウィンドウに表示されます。 サービスが実行されているコンカレンシー モードが表示され、各操作が呼び出され、操作数が表示されます。 コンカレンシー モードが Multiple
されると、サービスが複数のメッセージを同時に処理するため、呼び出し方法とは異なる順序で結果が返されます。 コンカレンシー モードを Single
に変更すると、サービスが各メッセージを順番に処理するため、呼び出された順序で結果が返されます。 クライアント ウィンドウで Enter キーを押して、クライアントをシャットダウンします。
サンプルを設定、ビルド、実行するには
Windows Communication Foundation サンプル のOne-Time セットアップ手順を実行していることを確認します。
Svcutil.exe を使用してプロキシ クライアントを生成する場合は、必ず
/async
オプションを含めてください。ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。
単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。