Nome da Aplicação na ConnectionString

by Israel Aece 5. October 2011 00:00

Muitas vezes temos várias aplicações que consomem o mesmo banco de dados. Cada uma dessas aplicações atuam em uma porção de dados, realizando uma tarefa específica. Nestes casos, é muito comum eles precisarem dos mesmos dados, e não há nada errado nisso.

Como há várias aplicações penduradas em cima de uma mesma base de dados, utilizando a mesma string de conexão, e na maioria das vezes, o mesmo usuário e senha, é difícil monitorar as requisições que estão sendo executadas no SQL Server, pois fica difícil identificar qual a origem (aplicação) da consulta/comando.

O Activity Monitor do SQL Server, ferramenta que nos permite monitorar em tempo real as conexões que estão abertas no momento, fornece várias colunas que detalham as informações de um processo específico. Entre essas colunas, temos uma chamada Application. Essa coluna, na configuração padrão da string de conexão para o SQL Server, sempre exibirá .Net Sql Client Data Provider.

Você pode customizar isso, através do atributo Application Name, que pode ser colocado na própria string de conexão, assim como podemos visualizar no código abaixo. Isso pode variar de acordo com cada aplicação, descrevendo para o monitor qual a aplicação que está aguardando ou executando o comando/consulta, independentemente se estiver utilizando um ORM ou não.

Initial Catalog=DBTeste;Data Source=.;Integrated Security=true;Application Name=Aplicacao01

Finalmente, depois dessa configuração devidamente realizada, se começarmos a realizar chamadas para o banco de dados SQL Server, essa configuração será levada até ele, e ao abrir a console de monitoramento, podemos visualizar tal informação, e rapidamente identificar qual é a aplicação que está realizando-a. A imagem abaixo ilustra a configuração em ação: 

Tags: ,

Data

WCF Web API Test Client

by Israel Aece 3. October 2011 22:21

Uma das ferramentas que a Microsoft criou para facilitar o teste de serviços WCF baseados em SOAP foi o WCF Test Client. Este utilitário permite consumir serviços simples através de alguns protocolos, sem a necessidade de ter que escrever uma aplicação cliente para apenas testá-lo.

Já para testar serviços baseandos em REST, esse utilitário não ajuda. Podemos recorrer ao navegador. Mas ele também não vai ajudar. Não é possível testar métodos POST diretamente, ele não consegue interpretar o formato JSON, não é possível customizar headers, etc. Por conta de todas essas "limitações", precisamos de uma ferramenta extra para nos auxiliar nos testes destes tipos de serviços. Isso nos leva a instalar uma aplicação de terceiros, como por exemplo, o Fiddler.

Apesar do Fiddler ajudar imensamente, ainda é um pouco complicado, pois precisamos descobrir quais são as URIs e seus respectivos métodos HTTP que foram disponibilizados pelo serviço. Para facilitar os testes, a Microsoft incorporou na WCF Web API uma ferramenta, escrita em jQuery, para que possamos testar os serviços tão logo quando eles forem criados, já listando os endereços disponíveis e com uma interface acessível no navegador que conduz facilmente os testes. Esta ferramenta é chamada de WCF Web API Test Client.

Por padrão, esse recurso está desabilitado. Para habilitá-lo precisamos customizar as configurações do serviço, utilizando a classe HttpConfiguration. Essa classe expõe uma propriedade boleana chamada EnableTestClient. O código abaixo ilustra como efetuar a configuração no arquivo Global.asax:

RouteTable.Routes.MapServiceRoute<ServicoDeUsuarios>
    ("usuarios", new HttpConfiguration() { EnableTestClient = true });

Ao definir esta propriedade como True, podemos acrescentar o sufixo "/test" na endereço do serviço, e a interface qual foi mencionada acima é exibida no navegador, e dali em diante, podemos utilizá-la para efetuar os testes. As imagens abaixo exibem alguns dos testes que foram capturados em um exemplo simples, que posta informações e também captura os dados que foram inseridos.

 

 

Tags: , ,

WCF

Recursos da Palestra do TechEd Brasil 2011

by Israel Aece 1. October 2011 10:40

Ontem eu fiz uma palestra no TechEd Brasil 2011, e o principal assunto abordado lá foi a nova API que a Microsoft está criando para facilitar a construção, hospedagem e consumo de serviços WCF baseados em REST.

O exemplo principal foi concetrado um projeto que nomeie de Techitter, que é composto por algumas aplicações simulando - de muito longe - o Twitter. A solução é composta por 4 projetos, onde um é o serviço, e onde concentra-se grande parte das novidades, um site em ASP.NET MVC que via jQuery posta e carrega as mensagens; outro projeto que consome a mesma API como um widget e, finalmente, uma aplicação WPF que também faz uso do serviço, consumindo o mesmo serviço via HttpClient, que também compõe a nova API. Para incrementar, existe o consumo de um serviço criado em outra tecnologia (NodeJs.exe), que foi consumido pelo serviço.

Gostaria de agradecer a todos os presentes, e também ao Rogerio Cordeiro pela oportunidade. Para aqueles interessados, o download do projeto pode ser baixado clicando aqui.

Tags: , ,

General | WCF

Caching em Serviços REST

by Israel Aece 28. August 2011 17:56

Uma das principais técnicas que são utilizadas na Web em busca de performance, é a utilização de técnicas de caching. Com elas, podemos armazenar em algum local uma cópia da página (HTML), arquivo, imagem, etc., que estamos acessando, para quando precisarmos novamente daquele recurso (URL) mais tarde, sermos atendidos de uma forma muito mais rápida.

A redução da latência e a diminuição do tráfego na rede são dois detalhes que alguma estratégia de caching pode ajudar a melhorar. O controle do caching pode estar definido do lado do servidor ou diretamente no cliente que consome o recurso. Sendo assim, ao acessar um recurso que já foi acessado recentemente, o usuário será servido quase que instantaneamente com o - mesmo - resultado.

As estratégias de caching são parte da especificação do protocolo HTTP, que como sabemos, foi desenhado para ser utilizado para acessar informações de sistemas distribuídos. A ideia principal do caching do HTTP, é tentar eliminar, quando possível, a necessidade de fazer novas requisições para um mesmo recurso, ou quando a requisição é necessária, tentar diminuir a quantidade de dados devolvidos.

Na verdade, dois detalhes importantes são definidos na especificação do protocolo, onde a estratégia de caching deve/pode controlar, a saber: expiração e validação. A expiração consiste em verificar se o recurso que está sendo solicitado já está em cache e continua sendo válido (ainda não expirado). Já a validação verifica se o recurso que está sendo re-solicitado ao servidor, sofreu ou não mudanças desde a última requisição, e caso não tenha, nada será retornado, afinal já temos a versão mais atualizada, e isso reduz a quantidade de informações - desnecessárias - sendo trafegadas.

Serviços REST, por estarem fortemente ligados ao protocolo HTTP, podem também fazer uso do caching oferecido pelo protocolo. A ideia deste artigo é demonstrar as opções que temos para configurar e, consequentemente, fazer uso de todos os benefícios oferecidos pelo caching. Para o exemplo, teremos um serviço que gerencia produtos, e haverá um único método que dado um identificador, retorna a instância do produto correspondente. Abaixo temos o código do serviço que utilizaremos pelos exemplos:

[ServiceContract]
[
    AspNetCompatibilityRequirements
    (
        RequirementsMode = AspNetCompatibilityRequirementsMode.Required
    )
]
public class Servico
{
    [WebGet(UriTemplate = "produtos/{produtoId}")]
    public Produto RecuperarProduto(string produtoId)
    {
        var produto =
            (
                from p in produtos
                where p.Id == Convert.ToInt32(produtoId)
                select p
            ).SingleOrDefault();

        return produto;
    }
}

Vou omitir a configuração do serviço aqui, mas neste primeiro momento estaremos utilizando a infraestrutura fornecida pelo WCF para a construção de serviços baseado em REST, que está disponível desde a versão 3.5 do .NET Framework (WCF Web Http). Ao subir este serviço, ele estará acessível e toda e qualquer requisição realizada pelo navegador chegará até o ele.

Todo o controle do caching do HTTP é realizado através de headers que foram criados e são assegurados pelo navegador e pelo servidor, para controlar o caching criado. Os serviços WCF fornecem alguns recursos que nos permitem acessar de forma mais simples estes headers, manipulando-os de acordo com a nossa necessidade. Os headers são divididos em cartegorias para manipular a expiração e a validação, e inicialmente vamos analisar aqueles que são utilizados para determinar a expiração de um recurso.

Expiração

O HTTP 1.1 introduziu um novo header, que é responsável por controlar a expiração. Este header é o Cache-Control, que pode receber vários valores que combinados, instruem o cliente a como efetuar e controlar o caching do recurso que está sendo devolvido. Um dos valores que podemos definir no Cache-Control é private, que determina que aquele conteúdo é exclusivo à um usuário (navegador), e pode eventualmente ser cacheado por ele. Podemos combiná-lo com outro valor que é o max-age, que define um número inteiro, que determina quantos segundos depois da requisição o conteúdo deverá ser mantido no cache.

Sendo assim, podemos recorrer ao contexto da requisição atual (WebOperationContext) dentro do método que está sendo disparado, e lá incluir o header que mencionamos acima. Temos que acessar a coleção de headers a partir da propriedade OutgoingResponse, que permite acessar as informações pertinentes à resposta.

WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control", "private, max-age=30");

Já quando não quiser que o cliente efetue o cache do recurso, podemos recorrer ao mesmo código acima para explicitamente determinar isso, determinando o valor do header Cache-Control como no-cache. O código abaixo exibe esta configuração:

WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control", "no-cache");

Note que para configurarmos o header Cache-Control, utilizamos uma classe pertinente ao WCF, que independe do host que estamos utilizando para hospedar o serviço. Quando utilizamos o IIS e, consequentemente, a infraestrutura do ASP.NET, podemos fazer uso de um recurso que já existe há algum tempo, que é o OutputCache.

A configuração do caching é através de cache profiles, que é um recurso onde você define todas as características do caching no arquivo de configuração (Web.config), e vincula essa configuração através do atributo AspNetCacheProfileAttribute. Abaixo temos o arquivo de configuração do serviço, e podemos notar a configuração do caching. A primeira configuração importante é habilitar o modelo de compatibilidade com o ASP.NET, e fazemos isso através do atributo aspNetCompatibilityEnabled do elemento serviceHostingEnvironment, definindo-o como True.

Em seguida, habilitamos o OutputCache definindo o atributo enableOutputCache como True. Logo após, temos um profile criado, que agrupa o conjunto de configurações de cache e o nomeia. Repare que estamos definindo o local do cache como "Server", o que determina que uma vez atendida a requisição para um determinado recurso, o cache será armazenado no servidor, e qualquer requisição subsequente, partindo ou não do mesmo cliente, será devolvida do cache criado, respeitando a duração de 60 segundos, ali também configurada. Isso fará com que qualquer complexidade que temos na execução daquele recurso, o preço será pago apenas uma única vez.

<configuration>
  <system.web>
    <caching>
      <outputCache enableOutputCache="true" />
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="CachingNoServidor"
               location="Server"
               duration="60"
               varyByParam="none"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
      <service name="ViaWcfWebHttp.Servico">
        <endpoint address=""
                  binding="webHttpBinding"
                  contract="ViaWcfWebHttp.Servico"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Como disse anteriormente, a amarração da configuração com o método do serviço é realizada através do atributo AspNetCacheProfileAttribute, que recebe em seu construtor uma string que representa o nome do profile que você quer aplicar para ele. Abaixo temos o serviço que foi ligeiramente modificado, decorado com o respectivo atributo:

[AspNetCacheProfile("CachingNoServidor")]
[WebGet(UriTemplate = "produtos/{produtoId}")]
public Produto RecuperarProduto(string produtoId) { }

Como esse caching refere-se ao servidor, os clientes nada sabem sobre ele. Inclusive na resposta ao cliente, por padrão, ele define o header Cache-Control como no-cache. Como já era de se esperar, podemos criar um novo profile, e lá definirmos o local do cache no cliente. Isso fará com que ao acessar o serviço, o cliente receberá o header Cache-Control definido como private e o atributo max-age definido como 60 (segundos), fazendo com que o navegador faça o caching do recurso. Abaixo temos o trecho do arquivo de configuração que exibe a adição deste profile de caching para o cliente:

<outputCacheSettings>
   <outputCacheProfiles>
      <add name="CachingNoCliente"
           location="Client"
           duration="60"
           varyByParam="none"/>
   </outputCacheProfiles>
</outputCacheSettings>

Validação

Acima vimos as opções que temos para controlarmos a expiração. Notamos que a expiração controla o período em que o recurso ficará disponível no caching do cliente (ou do servidor). Isso faz com que alguns recursos não sejam requisitados a todo momento, diminuindo a quantidade de informações que trafegam entre as partes. Só que dependendo do conteúdo que está sendo armazenado no cache, nem sempre podemos confiar cegamente no conteúdo que está salvo do lado do cliente.

Em certos cenários, o custo do round-trip é ignorado, em busca dos dados mais recentes possíveis, onde o prejuízo de visualizar uma informação defasada é muito maior. Só que as vezes, vamos até o servidor em busca dessa nova informação, e ela ainda não foi alterada, retornando para o cliente o mesmo conteúdo, atualizando a informação que temos localmente com exatamente, a mesma informação, ou seja, trafegamos uma informação que já tínhamos do lado do cliente. Para otimizar isso, temos uma técnica que chamamos de "GET condicional".

Essa técnica faz uso de entity tags (ETags), que consiste na adição de um header que é adicionado na resposta à uma requisição, que caracteriza a "versão" do conteúdo que foi devolvido ao cliente. Ao receber esse conteúdo e encaminhar esta tag nas requisições subsequentes, o serviço deverá ser capaz de identificar se houve ou não mudanças no objeto; caso exista, o serviço irá retornar a versão mais recente, do contrário, retornará o status 304 do HTTP, que indica que o recurso não teve mudanças, sem qualquer conteúdo na resposta, poupando assim que informações desnecessárias sejam enviadas ao cliente, que por sua vez, já possue a versão mais atual.

A implementação consiste em duas partes, sendo a primeira onde devemos nos preocupar em passar ao cliente as informações que caracterizam a "versão" do conteúdo, e a segunda parte, onde devemos criar dentro do serviço, a lógica para determinar se a versão que o cliente possui já é ou não a mais recente.

Para nosso exemplo, vamos incrementar a classe Produto com uma propriedade do tipo Guid chamada Versao, que define a versão do mesmo. Qualquer alteração que ocorra em qualquer uma das propriedades do produto, deverá atualizar o GUID. Já que essa propriedade irá caracterizar o versionamento, devemos apontar na resposta para o cliente o seu valor para que ele possa encaminhar ao mesmo através do header ETag. E para isso, vamos novamente recorrer a classe WebOperationContext, acessando a resposta que será enviada ao cliente e, finalmente, teremos o método SetETag, que como o próprio nome diz, permite definirmos a tag:

[WebGet(UriTemplate = "produtos/{produtoId}")]
public Produto RecuperarProduto(string produtoId)
{
    var produto =
        (
            from p in produtos
            where p.Id == Convert.ToInt32(produtoId)
            select p
        ).SingleOrDefault();

    WebOperationContext.Current.OutgoingResponse.SetETag(produto.Versao);
    return produto;
}

Ao utilizar uma ferramenta para monitorar o tráfego HTTP, podemos visualizar o resultado da requisição para o serviço acima. Note a presença do header ETag definido com o GUID gerado para nosso objeto:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 28 Aug 2011 20:26:53 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 202
ETag: "8e548670-8b75-4187-aedc-8182f46c3216"
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Connection: Close

<Produto xmlns="http://schemas.datacontract.org/2004/07/ViaWcfWebHttp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Descricao>Mouse Microsoft</Descricao><Id>1</Id><Valor>120.00</Valor></Produto>

Uma vez que o cliente recepciona essa requisição, as requisições subsequentes repassam o valor do header ETag para o serviço através de um outro header, chamado de If-None-Match, onde o serviço deverá averiguar se o produto foi alterado nesta janela de tempo, para determinar se o conteúdo do cliente deve ou não ser atualizado. Abaixo temos a requisição sendo realizada ao serviço depois de receber a ETag:

GET http://localhost:3911/Servico.svc/produtos/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US,pt-BR;q=0.5
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Host: localhost:3911
If-None-Match: "8e548670-8b75-4187-aedc-8182f46c3216"
Connection: Keep-Alive

Para efetuar essa validação do lado do serviço, há um método chamado CheckConditionalRetrieve, que está disponível a partir da propriedade IncomingRequest da classe WebOperationContext. Esse método recebe como parâmetro a ETag do produto. Se o produto não foi modificado, então a tag da requisição será a mesma, o que faz com que o método, internamente, aborte a requisição, devolvendo ao cliente o resultado 304 do HTTP, que caracteriza que nada foi mudado (NotModified). O código a seguir exibe a utilização deste método, e logo na sequência, temos a imagem que ilustra esse procedimento:

[WebGet(UriTemplate = "produtos/{produtoId}")]
public Produto RecuperarProduto(string produtoId)
{
    var produto =
        (
            from p int produtos
            where p.Id == Convert.ToInt32(produtoId)
            select p
        ).SingleOrDefault();

    WebOperationContext.Current.IncomingRequest.CheckConditionalRetrieve(produto.Versao);
    WebOperationContext.Current.OutgoingResponse.SetETag(produto.Versao);

    return produto;
}

WCF Web API

Como já comentei aqui, a Microsoft trabalha em um novo projeto chamado WCF Web API, que torna o desenvolvimento e consumo de serviços REST mais simples. Estes tipos de serviços também podem tirar proveito dos recursos de caching fornecidos pelo HTTP que vimos neste artigo.

Ao utilizar os objetos que representam as mensagens de requisição e resposta diretamente, você encontrá propriedades que configuram o caching no cliente. Você também pode optar por utilizar um message handler, para separar o que corresponde ao negócio do que compete a parte de infraestrutura.

Tags: , ,

WCF

Coletando e analisando arquivos de Dump

by Israel Aece 13. August 2011 15:37

Ao instalar uma aplicação em seu local de funcionamento, começa uma nova etapa, que é o monitoramento da mesma, que permite diagnosticar eventuais falhas e tentar trabalhar sempre de uma forma preventiva. Só que muitas vezes, estes problemas podem acontecer durante a execução, problemas estes que podem ser por falta de testes que atendiam aquelas condições, ou ainda, referente à algum problema de infraestrutura.

Se você toma o devido cuidado de catalogar as exceções que estão sendo disparadas, você pode recorrer aos arquivos onde elas estão armazenadas e inspecionar o que aconteceu e, consequentemente, encontrar a região do código responsável por aquele problema, e resolvê-lo, para em seguida, distribuir a correção para ele. Só que para detectar o problema, geralmente precisamos muito mais do que simplesmente o tipo da exceção que foi disparada, mas também quais foram os parâmetros informados, os valores que as variáveis estavam definidas naquele momento, e assim por diante.

Quando estamos em ambiente de desenvolvimento, podemos recorrer ao debugger do Visual Studio para executar a aplicação passo à passo, parando nos pontos que são importantes e naqueles que podem estar ocasionando o problema, e atenciosamente analisar e detectar o problema. Só que se essa aplicação já estiver em funcionamento, isso não é possível, pelo menos não de uma forma simples. Neste caso podemos recorrer a criação de um arquivo de dump da aplicação em questão. Ao gerar este arquivo, ele "fotografa" o estado atual do processo e gera várias informações para que possamos depurá-la mais tarde, algo mais ou menos parecido com o reporte de bugs do Windows.

Esse recurso é algo que podemos utilizar tanto em aplicações cliente como aquelas que rodam em um servidor, como é o caso de aplicações ASP.NET ou de serviços WCF. No caso de aplicações cliente, você pode recorrer ao Doctor Watson do Windows ou indo diretamente através da Task Manager. Como eu quero demonstrar a coleta do dump de um serviço WCF, vamos recorrer à segunda opção. Como sabemos, ao hospedar um serviço WCF no IIS, quem será responsável por executá-lo é um processo, chamado de w3wp.exe, que pode ser configurado através da opção Application Pools. Abaixo temos a imagem que ilustra como extrair o dump do processo do IIS:

Basicamente, este serviço recebe uma requisição e gera uma massa de informações para o respectivo cliente. Depois do arquivo de dump criado (extensão *.dmp), você receberá uma notificação informando onde ele foi salvo. Tudo o que precisamos fazer agora, é abrir o arquivo no Visual Studio 2010. A partir desta versão, o Visual Studio é capaz de interpretar esses arquivos. Ao abrí-lo, você irá se deparar com uma página, que detalha as informações sobre o processo. Podemos visualizar o nome do processo de onde o dump foi extraído, versão do sistema operacional, da CLR, etc. Outro ponto importante são os módulos que foram carregados à este processo, que aqui, por questões de espaço, não estão sendo exibidos todos eles. A imagem abaixo ilustra este resumo:

Como este arquivo contém o estado da aplicação naquele momento, o Visual Studio nos permite analisar o estado das informações (variáveis, parâmetros, etc.) que tínhamos, de uma forma tão simples quanto depurar a aplicação. Só que para isso funcionar, é necessário definirmos os símbolos, que são responsáveis por armazenarem informações para guiar o debugger até o código fonte. A opção "Set symbol paths" nos permite definir o endereço até o arquivo *.pdb, gerado durante o desenvolvimento do serviço.

Depois disso definido, podemos clicar na opção "Debug with Mixed", e o debugger do Visual Studio entra em ação. Ele lerá as informações contidas no arquivo de dump e irá exibí-las através das ferramentas de depuração que o próprio Visual Studio já nos fornece. A imagem que veremos a seguir já é uma dessas ferramentas: a janela Parallel Stacks. Essa janela é útil para depurarmos aplicações multi-thread, como é o caso de serviços WCF. Como podemos visualizar, temos a stack da execução e dentro dela, a chamada para o método Executar, que faz parte do serviço criado para o teste.

Ao clicar com o botão direito em um dos itens, podemos alternar entre as threads que estavam em execução naquele momento, acessando a operação Executar. Note que entre parênteses há o valor do parâmetro que está sendo passado para a operação. Abaixo temos a imagem que ilustra as três threads que temos em execução:

Finalmente, ao selecionar uma das opções listadas na imagem acima, somos encaminhados para o código correspondente, conseguindo visualizar o estado das informações, simplesmente passando o mouse por cima das mesmas. Além disso, você ainda pode recorrer as janelas de depuração que já existem há algum tempo no Visual Studio, como é caso das janelas de Threads, Modules e Locals, que trazem informações pertinentes aquele código que está sendo depurado no momento. A imagem abaixo exibe o estado das variáveis e parâmetros da operação Executar no momento em que o arquivo de dump foi gerado:

Tags:

WCF

Utilizando o utilitário netstat

by Israel Aece 10. August 2011 23:29

Quando hospedamos mais que um serviço em uma mesma máquina, pode ser difícil gerenciar, e de uma forma simples, visualizar o que está ativo e aceitando requisições. Se não temos o luxo de utilizar algum sistema de gerenciamento mais eficiente, como é o caso do AppFabric, podemos recorrer à um utilitário de linha de comando que existe no sistema operacional chamado netstat.

Este popular utilitário exibe uma lista com as conexões de rede estabelecidas no computador onde o mesmo está sendo executado. Se tivermos serviços WCF hospedados em uma determinada máquina, é possível visualizá-las através deste utilitário, e no mínimo, enxergar em qual porta eles encontram, se ela (porta) está aberta ou não e seu status. Abaixo temos um código de teste, que cria e abre vários hosts dentro de uma aplicação Console.

static void Main(string[] args)
{
    ServiceHost[] hosts = new ServiceHost[10];

    for (int i = 0; i < 10; i++)
    {
        var host = 
            new ServiceHost(typeof(Servico), 
                new Uri(string.Format("http://localhost:987{0}", i)));

        host.AddServiceEndpoint(typeof(IContrato), new BasicHttpBinding(), "srv");
        host.Open();
        hosts[i] = host;
    }

    Console.ReadLine();
}

Ao rodar esta aplicação, dez hosts são criados e abertos. Ao executar o utilitário netstat, essas conexões já são listadas, assim como podemos perceber na imagem abaixo:

Tags: ,

WCF

Utilizando o evento FirstChanceException

by Israel Aece 28. July 2011 22:58

Dependendo da tecnologia que estamos utilizando, há opções diferentes para o tratamento global de exceções, onde na maioria das vezes, nos preocupamos em efetuar o log de exceções não tratadas pela nossa aplicação. Por exceção não tratadas, entendam que sejam aquelas exceções que são disparadas e não estão envolvidas por um bloco try/catch.

Aquelas exceções que sabemos como lidar, prontamente interceptamos e exibimos uma mensagem amigável para o usuário, podendo ele ou o sistema, resolver ou sugerir a solução para o mesmo. Muitas vezes, para essas exceções "amigáveis", não nos preocupamos em catalogá-las e, consequentemente, não sabemos com qual frequência elas estão sendo disparadas. Informação essa que poderíamos utilizar para melhorar e tentar contornar o problema, para assim evitar que ela seja disparada frequentemente.

Como podemos perceber, há várias situações em que nos deparamos com o tratamento de exceções. Centralizar o tratamento facilita o log, mas não permite resolver o problema no local onde ela ocorre; já o tratamento local nos permite refinar a mensagem e como resolver o problema, mas acaba com uma explosão de blocos de tratamento de erros e, eventualmente, inclui um código para logar estas exceções.

Para facilitar isso, a partir da versão 4.0 do .NET Framework, temos um novo evento que foi adicionado à classe AppDomain, chamado de FirstChanceException. Esse evento é disparado momentos antes da CLR procurar dentro da call stack um tratador (bloco try/catch) para este tipo de exceção. Mesmo que o código que dispara a exceção estiver envolvido por um bloco catch com uma exceção específica, primeiramente o evento em questão será disparado, para em seguida, entregar a exceção para o respectivo tratador. Isso permitirá interceptar toda e qualquer exceção que aconteça, mesmo aquelas que já estejam devidamente tratadas.

É importante dizer que este evento é meramente informativo, ou seja, isso quer dizer que se a exceção não estiver sendo tratada, ela irá danificar a sua aplicação. Não há nenhum flag que nos permita definí-la como tratada. O código abaixo ilustra a sua utilização:

AppDomain.CurrentDomain.FirstChanceException += (obj, e) => EfetuarLog(e.Exception);
try
{
    throw new Exception("Algum Erro.");
}
catch (Exception)
{
    Console.WriteLine("Tratando o Erro.");
}

Tags:

.NET Framework

Revisão do Livro: Silverlight 4.0 Curso Completo

by Israel Aece 5. July 2011 23:36

Eu tenho acompanhado a evolução do Silverlight ao longo de sua existência, ainda quando ele se chamava WPF/E. Eu tenho me preocupado em estudar as stacks de comunicação para o consumo de serviços WCF, deixando alguns detalhes interessantes para focar especificamente na área de comunicação.

Para explorar um pouco melhor as capacidades do Silverlight, decidi ler um livro sobre o assunto. Como eu conheço os trabalhos do Luis Abreu, eu optei por utilizar o livro que ele escreveu sobre a versão 4.0 do Silverlight. O livro inicia com uma visão do que é o XAML e detalhes de sua estrutura. Depois dá uma volta pela customização e análise dos controles fornecidos pela tecnologia. DataBinding que também é um recurso extremamente rico em funcionalidades e facilidades, ele aborda com um carinho especial. Além disso, é falado sobre as opções de comunicação com serviços WCF. Há ainda também alguns recursos para aqueles que desejam explorar as possibilidades relacionadas à multimídia e animações. E como se não bastasse, ainda há alguns outros temas interessantes, que são essenciais para a execução e customização deste tipo de aplicação, e que possuem capítulos exclusivos, como é o caso do Out Of Browser e interação com o Javascript.

Mesmo para aqueles que usam WPF, podem tirar proveito deste livro, onde algumas seções são comuns para ambas tecnologias. Um livro curto, fácil de ler e bem ilustrado, que conta com uma didática simples, e que ao mesmo tempo, não deixa de abordar detalhes interessantes de mais baixo nível, para aqueles que gostam de entender como as coisas funcionam nos bastidores. Minha avaliação final é 9/10.

Tags:

General | WPF

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Host