Compartilhar via


Simultaneidade

O Exemplo de simultaneidade demonstra o uso de ServiceBehaviorAttribute com a enumeração ConcurrencyMode, que controla se uma instância de um serviço processa mensagens sequencialmente ou simultaneamente. O exemplo baseia-se na Introdução, que implementa o contrato de serviço ICalculator. Este exemplo define um novo contrato, ICalculatorConcurrency, que herda de ICalculator, fornecendo duas operações adicionais para inspecionar o estado da simultaneidade do serviço. Ao alterar a configuração de simultaneidade, você pode observar a alteração no comportamento executando o cliente.

Nesta amostra, o cliente é um aplicativo de console (.exe) e o serviço é hospedado pelos Serviços de Informações da Internet (IIS).

Observação

O procedimento de instalação e as instruções de compilação dessa amostra estão no final deste tópico.

Há três modos de simultaneidade disponíveis:

  • Single: cada instância de serviço processa uma mensagem por vez. Este é o modo de simultaneidade padrão.

  • Multiple: cada instância de serviço processa várias mensagens simultaneamente. A implementação do serviço deve ser thread-safe para usar esse modo de simultaneidade.

  • Reentrant: cada instância de serviço processa uma mensagem por vez, mas aceita chamadas reentrantes. O serviço só aceita essas chamadas quando está chamando. Reentrante é demonstrado no exemplo ConcurrencyMode.Reentrant.

O uso da simultaneidade está relacionado ao modo de instanciação. Na instanciação PerCall, a simultaneidade não é relevante, pois cada mensagem é processada por uma nova instância de serviço. Na instanciação Single, a simultaneidade Single ou Multiple é relevante, dependendo de a instância única processar mensagens sequencial ou simultaneamente. Na instanciação PerSession, qualquer um dos modos de simultaneidade pode ser relevante.

A classe de serviço especifica o comportamento de simultaneidade com o atributo [ServiceBehavior(ConcurrencyMode=<setting>)], conforme mostrado no exemplo de código a seguir. Alterando quais linhas são comentadas, você pode experimentar os modos de simultaneidade Single e Multiple. Lembre-se de recompilar o serviço depois de alterar o modo de simultaneidade.

// 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;
    }
}

O exemplo usa a simultaneidade Multiple com a instanciação Single por padrão. O código do cliente foi modificado para usar um proxy assíncrono. Isso permite que o cliente faça várias chamadas para o serviço sem aguardar uma resposta entre cada chamada. Você pode observar a diferença no comportamento do modo de simultaneidade do serviço.

Quando você executa a amostra, as solicitações de operação e as respostas são exibidas na janela do console do cliente. O modo de simultaneidade em que o serviço está sendo executado é exibido, cada operação é chamada e, em seguida, a contagem de operações é exibida. Observe que, quando o modo de simultaneidade é Multiple, os resultados são retornados em uma ordem diferente de como foram chamados, porque o serviço processa várias mensagens simultaneamente. Alterando o modo de simultaneidade para Single, os resultados são retornados na ordem em que foram chamados, pois o serviço processa cada mensagem sequencialmente. Pressione ENTER na janela do cliente para desligar o cliente.

Para configurar, compilar, e executar o exemplo

  1. Verifique se você executou as Amostras de Procedimento de Instalação Única para o Windows Communication Foundation.

  2. Se você usar Svcutil.exe para gerar o cliente de proxy, certifique-se de incluir a opção /async.

  3. Para compilar a edição .NET do C# ou do Visual Basic da solução, siga as instruções em Como compilar os exemplos do Windows Communication Foundation.

  4. Para executar a amostra em uma configuração de computador único ou entre computadores, siga as instruções contidas em Como executar as amostras do Windows Communication Foundation.