Dev (Back & Front)ARTIGO

Gerenciamento de instância no WCF

Olá a todos.

Vamos falar hoje sobre gerenciamento de instância no WCF e para que você possa entender esse artigo é necessário ter um conhecimento básico em WCF.

Existem três formas de realizar requisições através de um serviço WCFEssas formas são conhecidas como gerenciamento de instância e ajudam a melhorar o desempenho e a segurança do WCF.

Antes de explicar cada gerenciamento de instância, vou mostrar abaixo o código fonte que vamos utilizar para os exemplos. Lembre-se, é recomendado ter conhecimento em WCF.

Vamos utilizar um projeto Console. Primeiro vamos criar a seguinte Interface:

    [ServiceContract]<br />    public interface IContrato<br />    {<br />        [OperationContract]<br />        int Contador();<br />    }

Em seguida, uma classe que é herdada dessa Interface com a implementação do método Contador:

    [ServiceBehavior]<br />    public class Contrato: IContrato<br />    {<br />        private int _intContador;<br /><br />        public int Contador()<br />        {<br />            return _intContador++;<br />        }<br />    }

Em Program.cs, no método Main, digite o seguinte código:

static void Main(string[] args)<br /><br />        {<br /><br />            using (ServiceHost host = new ServiceHost(typeof(Contrato), new Uri[] { new Uri("net.tcp://localhost:9393") }))<br /><br />            {<br /><br />                host.Description.Behaviors.Add(new ServiceMetadataBehavior());<br /><br /><br /><br />                host.AddServiceEndpoint(typeof(IContrato), new NetTcpBinding(), "srv");<br /><br />                host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");<br /><br /><br /><br />                host.Open();<br /><br />                Console.WriteLine("[ O Serviço está rodando ]");<br /><br />                Console.ReadLine();<br /><br /><br /><br />                using (ChannelFactory<IContrato> f = new<br />ChannelFactory<IContrato>(new NetTcpBinding(),<br />"net.tcp://localhost:9393/srv"))<br /><br />                {<br /><br />                    var channel = f.CreateChannel();<br /><br /><br /><br />                    for (int intContador = 0; intContador < 5; intContador++)<br /><br />                    {<br /><br />                        Console.WriteLine(channel.Contador().ToString());<br /><br />                    }<br /><br />                }<br /><br /><br /><br />                using (ChannelFactory<IContrato> f = new<br />ChannelFactory<IContrato>(new NetTcpBinding(),<br />"net.tcp://localhost:9393/srv"))<br /><br />                {<br /><br />                    var channel = f.CreateChannel();<br /><br /><br /><br />                    for (int intContador = 0; intContador < 5; intContador++)<br /><br />                    {<br /><br />                        Console.WriteLine(channel.Contador().ToString());<br /><br />                    }<br /><br />                }<br /><br /><br /><br />                Console.ReadLine();<br /><br />            }

Para esse exemplo, estou criando o host e a chamada ao serviço em uma única aplicação, isso não é correto em um projeto, mas para um exemplo será útil. Depois de criar o host, crio dois proxy (instância do serviço) que  realizaram cinco requisições cada um.

Bem, com esse código pronto, vamos às explicações.

PerSession

Esse é a instância padrão do WCF. Quando a aplicação cliente cria uma proxy, esse proxy irá realizar todas as conexões com o serviço que o cliente chamar, até que o método Close (ou Dispose) seja chamado e o proxy seja encerrado.

Enquanto o proxy não for fechado, todas as alterações feitas nos membros internos do serviço (como em uma propriedade global, como no nosso exemplo em _intContador) serão armazenadas. Caso a aplicação cliente crie dois proxy, cada um deles irá controlar sua memória, não interferindo um proxy no outro.

Como já escrevi, o PerSession é a instância default do WCF, nesse caso não precisamos informá-la quando desejamos utilizar, mas em nosso exemplo vamos especificar. Vamos dizer ao WCF para trabalhar com PerSession na classe do serviço (no nosso exemplo, na classe Contrato), como mostrado abaixo:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]

Ao executar nosso exemplo, temos o seguinte resultado:

A propriedade _intContador é incrementada sempre que o proxy é chamado, porém quando o proxy é finalizado e um novo é criado, o _intContador começa do zero (propriedade int por padrão começa com valor zero), pois a instância anterior foi perdida.

PerCall

Diferente do PerSession, o PerCall cria uma nova requisição do proxy, ou seja, quando a operação é finalizada, o proxy é removido da memória. Para utilizarmos o PerCall, precisamos alterar na classe Contador o InstanceContextMode, conforme exemplo abaixo:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

Ao executar nosso exemplo após a alteração, temos o seguinte resultado:

O resultado sempre será zero, porque apesar de realizar N requisições ao serviço, a propriedade _intContador não é incrementada.

Single

Single tem uma maneira diferente de se comportar. Existir apenas uma única instância do proxy que irá servir para todas as requisições, mesmo que o Close ou Dispose sejam chamados ou que um novo objeto proxy seja criado. Para utilizarmos o Single, precisamos alterar na classe Contador o InstanceContextMode, conforme exemplo abaixo.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

Mesmo descartando o primeiro proxy, quando começamos a utilizar o segundo proxy, o _intContador continua sendo incrementando com o valor que foi finalizado pelo primeiro proxy, conforme podemos ver na imagem abaixo:

Você deve estar perguntando é a melhor. Bom, isso depende… ninguém melhor do que você para decidir qual tipo de gerenciamento de instância é a melhor para a sua solução. Só devemos tomar cuidado porque a instância está ligada ao binding, ou seja, nem todos os bindings (como BasicHttpBinding) suportam esse exemplo que implementamos.

O código-fonte desse exemplo está disponível aqui.

Espero que tenham gostado e até a próxima.

é Analista de Sistema com carreira em empresas de tecnologia, atuando em soluções de sistemas e TI para diversos segmentos de negócios, além de definir e planejar metodologias de desenvolvimento de software. É bacharel em Administração com gestão em TI, pós-graduado em Projetos e Desenvolvimento de Sistemas para web e cursa pós-graduação em Inteligência de Negócios (BI).

Ver perfil