次の方法で共有


コンカレンシー

コンカレンシー サンプルでは、ConcurrencyMode列挙体でServiceBehaviorAttributeを使用する方法を示します。この列挙は、サービスのインスタンスがメッセージを順番に処理するか、同時に処理するかを制御します。 このサンプルは、 サービス コントラクトを実装するICalculatorに基づいています。 このサンプルでは、ICalculatorから継承する新しいコントラクト ICalculatorConcurrencyを定義し、サービスコンカレンシーの状態を検査するための 2 つの追加操作を提供します。 コンカレンシー設定を変更することで、クライアントを実行することで動作の変化を観察できます。

このサンプルでは、クライアントはコンソール アプリケーション (.exe) であり、サービスはインターネット インフォメーション サービス (IIS) によってホストされています。

このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。

使用できるコンカレンシー モードは 3 つあります。

  • Single: 各サービス インスタンスは、一度に 1 つのメッセージを処理します。 これは既定のコンカレンシー モードです。

  • Multiple: 各サービス インスタンスは、複数のメッセージを同時に処理します。 このコンカレンシー モードを使用するには、サービスの実装がスレッド セーフである必要があります。

  • Reentrant: 各サービス インスタンスは一度に 1 つのメッセージを処理しますが、再入可能な呼び出しを受け入れます。 サービスは、呼び出し時にのみこれらの呼び出しを受け入れます。再入は、 ConcurrencyMode.Reentrant サンプルで示されています。

コンカレンシーの使用は、インスタンス化モードに関連します。 PerCallインスタンス化では、各メッセージは新しいサービス インスタンスによって処理されるため、コンカレンシーは関係ありません。 Singleインスタンス化では、単一インスタンスがメッセージを順番に処理するか同時に処理するかに応じて、SingleまたはMultipleコンカレンシーが関連します。 PerSessionインスタンス化では、コンカレンシー モードのいずれかが関連している可能性があります。

サービス クラスは、次のコード サンプルに示すように、 [ServiceBehavior(ConcurrencyMode=<setting>)] 属性を使用してコンカレンシー動作を指定します。 コメント アウトする行を変更することで、 SingleMultiple コンカレンシー モードを試すことができます。 コンカレンシー モードを変更した後は、サービスをリビルドすることを忘れないでください。

// 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 キーを押して、クライアントをシャットダウンします。

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

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

  2. Svcutil.exe を使用してプロキシ クライアントを生成する場合は、必ず /async オプションを含めてください。

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

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