Desenvolvimento - WCF/WPF

Timeouts do WCF

Como sabemos, o WCF é altamente configurável, permitindo com que grande parte das informações que ele utiliza em tempo de execução, sejam configuradas de acordo com a nossa necessidade. Entre essas centenas de configurações, temos vários tipos de timeouts espalhados pelo lado do cliente e do serviço.

por Israel Aéce



Como sabemos, o WCF é altamente configurável, permitindo com que grande parte das informações que ele utiliza em tempo de execução, sejam configuradas de acordo com a nossa necessidade. Entre essas centenas de configurações, temos vários tipos de timeouts espalhados pelo lado do cliente e do serviço.

timeouts que somente estarão acessíveis quando você estiver utilizando alguma funcionalidade específica, como é o caso de transações, mensagens confiáveis, etc., e também há timeouts que, independentemente das características do serviço, sempre estarão disponíveis para que possamos ajustá-los quando o valor padrão não nos atende.

Para iniciar, a classe ServiceHost possui duas propriedades, que recebem um TimeSpan, chamadas OpenTimeout e CloseTimeout. Através da propriedade OpenTimeout, podemos definir um intervalo de tempo que o runtime do WCF deve esperar ao tentar abrir o host. Invocar o método Open da classe ServiceHost, faz com que uma série de tarefas sejam efetuadas antes que o teu serviço esteja efetivamente disponível para consumo. Com o timeout de abertura, podemos determinar por quanto tempo podemos esperar até que isso seja concluída. Como já era de esperar, ao invocar o método Close da classe ServiceHost, várias tarefas serão realizadas com a finalidade de desfazer tudo aquilo que fui montado pela abertura do host. E, como o próprio nome diz, a propriedade CloseTimeout nos permite definir um intervalo de tempo que podemos esperar até que tudo isso seja encerrado.

Por padrão, o valor definido para a propriedade OpenTimeout é 00:01:00, enquanto para CloseTimeout temos 00:00:10. Felizmente também podemos configurar esses valores através do modelo declarativo, ou seja, através do arquivo de configuração. Para isso, basta utilizar o sub-elemento timeouts do elemento host, assim como podemos visualizar no código abaixo:

<system.serviceModel>
<services>
<service name="GestorDeCredito">
<host>
<timeouts closeTimeout="00:01:20" openTimeout="00:00:20"/>
</host>
</service>
</services>
</system.serviceModel>

Todos os bindings nativos do WCF e aqueles que são customizados que, herdam direta ou indiretamente da classe Binding. Essa classe fornece quatro propriedades relacionadas à timeouts, que podem ser configuradas de forma declarativa ou imperativa. As propriedades são: CloseTimeout, OpenTimeout, ReceiveTimeout e SendTimeout.

A finalidade das propriedades CloseTimeout e OpenTimeout do binding é configurar a comunicação entre o cliente/serviço. Quando você se comunica com o serviço, ou quando o serviço se comunica com o cliente, existem várias tarefas (mensagens) que são realizadas (trocadas) entre as partes, antes da mensagem da operação em si. Já através da propriedade ReceiveTimeout, podemos definir um intervalo de tempo em que, se nenhuma mensagem chegar até ele dentro deste período de tempo (aqui não é contemplado mensagens de infraestrutura), a conexão será encerrada e, consequentemente, a instância da classe que representa o serviço será descartada. A comunicação entre o cliente e o serviço envolve vários recursos custosos, e manter isso sem necessidade pode, em pouco tempo, consumir muito mais memória do que realmente é preciso. Justamente por isso que você deve avaliar cuidadosamente o intervalo necessário para manter a sua conexão ativa. Por fim, temos a propriedade SendTimeout, que por sua vez, determina o tempo em que o WCF aguarda até que uma operação seja completamente efetuada.

Ainda falando sobre timeouts, há uma outra propriedade chamada InactivityTimeout (utilizada pelas Reliable Messages). Se nenhuma mensagem for transmitida (incluindo mensagens de infraestrutura, como acknowledgements) durante o intervalo de tempo determinado por essa propriedade, a sessão será descartada e, quando omitido, o valor padrão é 10 minutos. Quando você faz uso das realiable messages, é importante que as propriedades InactivityTimeout e ReceiveTimeout estejam sincronizadas, pois do contrário, não ter a propriedade InactivityTimeout maior que ReceiveTimeout, não evitará o termino da sessão.

Atente-se para estas propriedades. Elas não são publicadas no documento WSDL e, consequentemente, não são automaticamente propagadas para o cliente. Ao fazer a referência de um serviço em uma aplicação cliente, os valores que você visualiza no arquivo de configuração são apenas os valores padrão de cada propriedade. Compete a você alterar para ajustar de acordo com a sua necessidade.
Israel Aéce

Israel Aéce - Especialista em tecnologias de desenvolvimento Microsoft, atua como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. Como instrutor Microsoft, leciona sobre o desenvolvimento de aplicações .NET. É palestrante em diversos eventos Microsoft no Brasil e autor de diversos artigos que podem ser lidos a partir de seu site http://www.israelaece.com/. Possui as seguintes credenciais: MVP (Connected System Developer), MCP, MCAD, MCTS (Web, Windows, Distributed, ASP.NET 3.5, ADO.NET 3.5, Windows Forms 3.5 e WCF), MCPD (Web, Windows, Enterprise, ASP.NET 3.5 e Windows 3.5) e MCT.