Sessões,instanciação e simultaneidade

Uma sessão é uma correlação de todas as mensagens enviadas entre dois pontos de extremidade. Instanciação refere-se ao controle do tempo de vida dos objetos de serviço definidos pelo usuário e seus objetos relacionados InstanceContext. Simultaneidade é o termo dado ao controle do número de threads em execução em um InstanceContext ao mesmo tempo.

Este tópico descreve essas configurações, como usá-las e as várias interações entre elas.

Sessões

Quando um contrato de serviço define a propriedade ServiceContractAttribute.SessionMode para SessionMode.Required, esse contrato está especificando que todas as chamadas (ou seja, as trocas de mensagens subjacentes que dão suporte às chamadas) devem fazer parte da mesma conversa. Se um contrato especificar que ele permite sessões, mas não requer uma, os clientes podem se conectar e estabelecer ou não uma sessão. Se a sessão terminar e uma mensagem for enviada pelo mesmo canal baseado em sessão, uma exceção será gerada.

As sessões do WCF têm os seguintes principais recursos conceituais:

  • Eles são iniciados e encerrados explicitamente pelo aplicativo de chamada.

  • As mensagens entregues durante uma sessão são processadas na ordem em que são recebidas.

  • As sessões correlacionam um grupo de mensagens em uma conversa. O significado dessa correlação é uma abstração. Por exemplo, um canal baseado em sessão pode correlacionar mensagens com base em uma conexão de rede compartilhada, enquanto outro canal baseado em sessão pode correlacionar mensagens com base em uma marca compartilhada no corpo da mensagem. Os recursos que podem ser derivados da sessão dependem da natureza da correlação.

  • Não há nenhum armazenamento de dados geral associado a uma sessão WCF.

Se você estiver familiarizado com a classe System.Web.SessionState.HttpSessionState em aplicativos ASP.NET e a funcionalidade que ela fornece, você poderá observar as seguintes diferenças entre esse tipo de sessão e as sessões do WCF:

  • As sessões ASP.NET são sempre iniciadas pelo servidor.

  • As sessões ASP.NET são implicitamente desordenadas.

  • As sessões ASP.NET fornecem um mecanismo geral de armazenamento de dados entre solicitações.

Aplicativos cliente e aplicativos de serviço interagem com sessões de formas diferentes. Os aplicativos cliente iniciam sessões e, em seguida, recebem e processam as mensagens enviadas dentro da sessão. Aplicativos de serviço podem usar sessões como um ponto de extensibilidade para incluir comportamento adicional. Isso é feito trabalhando diretamente com o InstanceContext ou por meio da implementação de um provedor de contexto de instância personalizada.

Instanciação

O comportamento de instanciação (definido usando a propriedade ServiceBehaviorAttribute.InstanceContextMode) controla como o InstanceContext é criado em resposta às mensagens de entrada. Por padrão, cada InstanceContext está associado a um objeto de serviço definido pelo usuário, portanto (no caso padrão) a propriedade InstanceContextMode também controla a instanciação de objetos de serviço definidos pelo usuário. A enumeração InstanceContextMode define os modos de instanciação.

Os seguintes modos de instanciação estão disponíveis:

  • PerCall: um novo InstanceContext (e, portanto, objeto de serviço) é criado para cada solicitação do cliente.

  • PerSession: um novo InstanceContext (e, portanto, objeto de serviço) é criado para cada nova sessão de cliente e mantida para o tempo de vida dessa sessão (isso requer uma associação que dá suporte à sessão).

  • Single: um único InstanceContext (e, portanto, objeto de serviço) manipula todas as solicitações do cliente para o tempo de vida do aplicativo.

O exemplo de código a seguir mostra o valor InstanceContextMode padrão, em que PerSession é explicitamente definido em uma classe de serviço.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorInstance
{
    ...  
}  

E enquanto a propriedade ServiceBehaviorAttribute.InstanceContextMode controla com que frequência o InstanceContext é liberado, as propriedades OperationBehaviorAttribute.ReleaseInstanceMode e ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete controlam quando o objeto de serviço é liberado.

Serviços singleton conhecidos

Às vezes, uma variação em objetos de serviço de instância é útil: você pode criar um objeto de serviço por conta própria e criar o host de serviço usando esse objeto. Para fazer isso, você também deve definir a propriedade ServiceBehaviorAttribute.InstanceContextMode como Single ou uma exceção será gerada quando o host de serviço for aberto.

Use o construtor ServiceHost(Object, Uri[]) para criar esse serviço. Ele fornece uma alternativa para implementar um System.ServiceModel.Dispatcher.IInstanceContextInitializer personalizado quando você deseja quer uma instância de objeto específica para uso por um serviço singleton. Você pode usar essa sobrecarga quando o tipo de implementação de serviço for difícil de construir (por exemplo, se ele não implementar um construtor público sem parâmetros).

Observe que quando um objeto é fornecido a esse construtor, alguns recursos relacionados ao comportamento de instanciação do WCF (Windows Communication Foundation) funcionam de forma diferente. Por exemplo, a chamada InstanceContext.ReleaseServiceInstance não tem efeito quando uma instância de objeto singleton é fornecida. Da mesma forma, qualquer outro mecanismo de liberação de instância é ignorado. O ServiceHost sempre se comporta como se a propriedade OperationBehaviorAttribute.ReleaseInstanceMode estivesse definida como ReleaseInstanceMode.None para todas as operações.

Compartilhando objetos InstanceContext

Você também pode controlar qual canal ou chamada baseado em sessão está associado a qual objeto InstanceContext, por meio da execução dessa associação por conta própria.

Simultaneidade

Simultaneidade é o controle do número de threads ativos em um InstanceContext a qualquer momento. Isso é controlado usando ServiceBehaviorAttribute.ConcurrencyModecom a enumeração ConcurrencyMode.

Os três modos de simultaneidade a seguir estão disponíveis:

  • Single: cada contexto de instância tem permissão para ter no máximo um thread processando mensagens no contexto da instância por vez. Outros threads que desejam usar o mesmo contexto de instância devem ser bloqueados até que o thread original saia do contexto da instância.

  • Multiple: cada instância de serviço pode ter vários threads processando 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 de reentrada. O serviço só aceita essas chamadas quando está chamando por meio de um objeto cliente do WCF.

Observação

Pode ser difícil escrever de modo bem-sucedido, entender e desenvolver código que use com segurança mais de um thread. Antes de usar valores Multiple ou Reentrant, verifique se o serviço foi projetado corretamente para esses modos. Para obter mais informações, consulte ConcurrencyMode.

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 um novo InstanceContext e, portanto, nunca mais de um thread está ativo no InstanceContext.

O exemplo de código a seguir demonstra a configuração da propriedade ConcurrencyMode como Multiple.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorConcurrency
{
    ...  
}  

Sessões interagem com configurações de InstanceContext

Sessões e InstanceContext interagem dependendo da combinação do valor da enumeração SessionMode em um contrato e da propriedade ServiceBehaviorAttribute.InstanceContextMode na implementação do serviço, que controla a associação entre canais e objetos de serviço específicos.

A tabela a seguir mostra o resultado de um canal de entrada que dá suporte a sessões ou não dá suporte a sessões, dada a combinação de um serviço dos valores da propriedade ServiceContractAttribute.SessionMode e da propriedade ServiceBehaviorAttribute.InstanceContextMode.

InstanceContextMode Required Allowed NotAllowed
PerCall - Comportamento com canal de sessão: uma sessão e um InstanceContext para cada chamada.
- Comportamento com canal sem sessão: uma exceção é gerada.
- Comportamento com canal de sessão: uma sessão e um InstanceContext para cada chamada.
- Comportamento com canal sem sessão: um InstanceContext para cada chamada.
- Comportamento com canal de sessão: uma exceção é gerada.
- Comportamento com canal sem sessão: um InstanceContext para cada chamada.
PerSession - Comportamento com canal de sessão: uma sessão e um InstanceContext para cada canal.
- Comportamento com canal sem sessão: uma exceção é gerada.
- Comportamento com canal de sessão: uma sessão e um InstanceContext para cada canal.
- Comportamento com canal sem sessão: um InstanceContext para cada chamada.
- Comportamento com canal de sessão: uma exceção é gerada.
- Comportamento com canal sem sessão: um InstanceContext para cada chamada.
Single - Comportamento com canal de sessão: uma sessão e um InstanceContext para todas as chamadas.
- Comportamento com canal sem sessão: uma exceção é gerada.
- Comportamento com canal de sessão: uma sessão e InstanceContext para o singleton criado ou especificado pelo usuário.
- Comportamento com canal sem sessão: um InstanceContext para o singleton criado ou especificado pelo usuário.
- Comportamento com canal de sessão: uma exceção é gerada.
- Comportamento com canal sem sessão: um InstanceContext para cada singleton criado ou para o singleton especificado pelo usuário.

Confira também