다음을 통해 공유


동시성

동시성 샘플은 열거형 ServiceBehaviorAttribute와 함께 ConcurrencyMode를 사용하는 방법을 보여 줍니다. 이 열거형은 서비스 인스턴스가 메시지를 순차적으로 처리할지 아니면 동시에 처리할지를 제어합니다. 샘플은 Getting Started에 기반하며, ICalculator 서비스 계약을 구현합니다. 이 샘플은 ICalculatorConcurrency라는 새 계약을 정의하며, 이는 ICalculator로부터 상속받아 서비스 동시성 상태를 검사하는 두 가지 추가 작업을 제공합니다. 동시성 설정을 변경하면 클라이언트를 실행하여 동작의 변화를 관찰할 수 있습니다.

이 샘플에서 클라이언트는 콘솔 애플리케이션(.exe)이며 서비스는 IIS(인터넷 정보 서비스)에서 호스팅됩니다.

비고

이 샘플에 대한 설치 절차 및 빌드 지침은 이 항목의 끝에 있습니다.

다음 세 가지 동시성 모드를 사용할 수 있습니다.

  • Single: 각 서비스 인스턴스는 한 번에 하나의 메시지를 처리합니다. 기본 동시성 모드입니다.

  • Multiple: 각 서비스 인스턴스는 여러 메시지를 동시에 처리합니다. 이 동시성 모드를 사용하려면 서비스 구현이 스레드로부터 안전해야 합니다.

  • Reentrant: 각 서비스 인스턴스는 한 번에 하나의 메시지를 처리하지만 재진입 호출을 허용합니다. 서비스는 자체적으로 호출을 수행할 때만 이 같은 호출을 수락합니다. 재진입은 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;
    }
}

이 샘플은 기본적으로 Multiple 동시성과 Single 인스턴싱을 함께 사용합니다. 클라이언트 코드가 비동기 프록시를 사용하도록 수정되었습니다. 이렇게 하면 클라이언트가 각 호출 간의 응답을 기다리지 않고 서비스에 대해 여러 차례 호출할 수 있습니다. 서비스 동시성 모드의 동작 차이를 확인할 수 있습니다.

샘플을 실행하면 작업 요청 및 응답이 클라이언트 콘솔 창에 표시됩니다. 서비스가 실행 중인 동시성 모드가 표시되고 각 작업이 호출된 다음 작업 수가 표시됩니다. 동시성 모드인 경우 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 샘플실행의 지침을 따릅니다.