Habilitando o Performance Counter no WCF

Como eu comentei aqui, o WCF fornece vários contadores de performance que você pode utilizar para monitorar os serviços. Há vários tipos de contadores, que mensuram pontos cruciais de toda a infraestrutura do WCF. A imagem abaixo ilustra o monitoramento das instâncias (das classes que representam o serviço) que são criadas, e a quantidade de chamadas por segundo.

Ao adicionar um contador, você pode escolher monitorar esses índices para todos os serviços que rodam naquela máquina ou, se desejar, poderá monitorar esse contador para um serviço específico. Para isso, ao adicionar um contador, selecione a instância correspondente, que é representada pelo endereço onde o serviço está exposto. Se por algum motivo, quiser ler essas informações a partir de uma aplicação customizada, então você deve recorrer ao uso da classe PerformanceCounter e PerformanceCounterCategory.

Anúncios

Utilizando Exceptions como Faults

Quando construímos um serviço WCF, podemos utilizar o atributo FaultContractAttribute um tipo, que representará o problema que ocorreu durante o processamento daquela mensagem. O tipo especificado ali vai estar disponível para o cliente através de uma FaultException<T>, onde T representará os detalhes do erro. O parâmetro genérico T não tem nenhuma constraint, o que permite colocar qualquer tipo (desde que ele seja serializável). Para maiores detalhes, consulte essas fontes.

Como o tipo informado através do atributo FaultContractAttribute está aberto, nada impede de colocarmos ali um tipo que herde direta ou indiretamente da classe Exception. Definindo exceções que foram criadas pelo .NET Framework, não haverá problemas, já que elas existem do outro lado. As dificuldades começam quando é preciso propagar exceções customizadas, aquelas que são herdadas a partir da classe Exception. O grande problema aqui é que o serializador padrão do WCF, que é o DataContractSerializer, não serializa tipos complexos por questões de interoperabilidade. Com essa “limitação”, a classe Exception (ou uma de suas derivadas) sofrerá com isso, já que ela expõe uma propriedade chamada Data, que retorna a instância de um objeto que implementa a Interface IDictionary.

Para resolvermos isso, a boa prática é que sempre criar Faults. Dessa forma, você criará uma classe para detalhar o problema para os clientes, sem a necessidade de manipular exceções. Com isso, ao invés de disparar uma exceção customizada, você dispara uma FaultException<T>, onde T será essa classe que detalhará o problema ocorrido. Agora, se você tiver a possibilidade de compartilhar os tipos, então a exceção customizada funcionará, já que os clientes a conhecem, mas você pagará o preço da interoperabilidade.