<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Azure Blog Ninja - Fabricio Catae</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/fcatae/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/fcatae/feed.xml</link>
    <description>O desenvolvimento moderno tem arquiteturas baseadas em Cloud</description>
    <lastBuildDate>Thu, 09 Aug 2018 12:01:23 GMT</lastBuildDate>
    <language>pt_BR</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Hit Refresh</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/hit-refresh</link>
      <pubDate>Thu, 09 Aug 2018 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4985</guid>
      <description><![CDATA[Olá pessoal!

Estava revendo meu blog e vi que meu primeiro post foi em agosto de 2009 (já faz...]]></description>
      <content:encoded><![CDATA[<strong>Olá pessoal!</strong>

Estava revendo meu blog e vi que meu <a href="https://blogs.msdn.microsoft.com/fcatae/2009/08/21/introduo/">primeiro post</a> foi em agosto de 2009 (já faz quase 10 anos). Ao longo dessa jornada, pude compartilhar um pouco da experiência de campo como Premier Field Engineer (PFE) de SQL Server.

Mas houve mudanças…

<strong>Em 2014 mudei para o time de Evangelismo da Microsoft, trabalhando com games (Mobile, PC, XBox).</strong>
<ul>
 	<li>Criei um blog de desenvolvimento de jogos. <a href="http://aka.ms/jogos">http://aka.ms/jogos</a></li>
 	<li>Ensinei muitas crianças a programar com o Kudu (<a href="https://blogs.msdn.microsoft.com/jogos/2015/03/24/ensinando-a-programar-kodu-game-labs/" title="https://blogs.msdn.microsoft.com/jogos/2015/03/24/ensinando-a-programar-kodu-game-labs/">https://blogs.msdn.microsoft.com/jogos/2015/03/24/ensinando-a-programar-kodu-game-labs/</a>)</li>
 	<li>Tinha até um canal de eventos. <a href="https://channel9.msdn.com/Events/Games-Brasil" title="https://channel9.msdn.com/Events/Games-Brasil">https://channel9.msdn.com/Events/Games-Brasil</a></li>
</ul>
<strong>Em 2015 investimos pesado no evangelismo do Microsoft Edge (sucessor do Internet Explorer).</strong>
<ul>
 	<li>Criei artigos sobre HTML5 no blog do Lab27 (<a href="http://www.lab27.com.br/" title="http://www.lab27.com.br/">http://www.lab27.com.br/</a>, que foi desligado!)</li>
 	<li>Gravei vídeos (<a href="https://www.youtube.com/channel/UCXF9mbDYamSiS43WpSnDiaw" title="https://www.youtube.com/channel/UCXF9mbDYamSiS43WpSnDiaw">https://www.youtube.com/channel/UCXF9mbDYamSiS43WpSnDiaw</a>)</li>
 	<li>Participei de eventos usando a camisa do Internet Explorer (!!!) e do Edge</li>
</ul>
<strong>Em 2016 iniciei os trabalhos com nuvem (Microsoft Azure).</strong>
<ul>
 	<li>Escrevi muito código no GitHub (<a href="https://github.com/fcatae">https://github.com/fcatae</a>)</li>
 	<li>Criamos o projeto ARDA para apontamento de horas do time (<a href="https://github.com/CSELATAM/arda">https://github.com/CSELATAM/arda</a>)</li>
 	<li>Atuei com o time de Startups (que mundo diferente!) para adoção do Azure</li>
</ul>
<strong>Em 2017 fiquei dedicado a um único cliente: Linx, atuando como Arquiteto de Cloud.</strong>
<ul>
 	<li>Azure: Virtual Machine, VM Scale Sets, Storage Account, WebApps, EventHub, etc..</li>
 	<li>DevOps: Acompanhamento do processo de Build e Release</li>
 	<li>Microserviços: Projetos com API REST e backend NoSQL</li>
</ul>
<strong>Ainda em 2017 me tornei professor de pós-graduação na FIAP.</strong>
<ul>
 	<li>Curso MBA: <a href="https://www.fiap.com.br/mba/mba-em-arquitetura-e-desenvolvimento-na-plataforma-net/">Arquitetura e Desenvolvimento na Plataforma .NET</a></li>
 	<li>Inclusão dos temas de Cloud e NoSQL na disciplina de Persistência de Dados</li>
 	<li>Escrevi o "famoso" artigo: <a href="https://blogs.msdn.microsoft.com/fcatae/2017/07/10/entity-framework-code-first-database-never/">Entity Framework: Code-First, Database-Never</a></li>
</ul>
Apesar de todas essas mudanças, sempre continuei escrevendo artigos sobre SQL Server. É um assunto que gosto muito! Foi essa paixão que me ajudou a continuar escrevendo.

Entretanto, hoje sinto que não tenho mais tanta experiência como antes. Os últimos posts nem foram sobre SQL, mas sobre os aprendizados de um projeto chamado <a href="https://github.com/cselatam/arda">ARDA</a>. Sinto que chegou a hora de parar de escrever. Há vários profissionais que continuam trabalhando diariamente com SQL Server e que publicam material de melhor conteúdo.

<strong>HIT REFRESH</strong>

Acabei de rodar um <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-cycle-errorlog-transact-sql">sp_cycle_errorlog</a> (ou receber um SIGHUP, do Unix). Estava na hora de me "reconfigurar":
<ul>
 	<li>Oficialmente desde julho de 2018 meu cargo é <strong>Senior Software Engineer</strong>, atuando na área de Open Source e Inovação.</li>
 	<li>Passei na prova de certificação <strong><a href="https://training.linuxfoundation.org/certification/linux-foundation-certified-sysadmin-lfcs/">LFCS (Linux Foundation Certified Sysadmin)</a></strong>.</li>
 	<li>Retornei ao blog para escrever novos artigos.</li>
</ul>
Embora as futuras publicações talvez não sejam assuntos muito atraentes ao DBA (desculpe!), pelo menos consigo dar continuidade ao blog. Aprendi muito com o SQL Server e ele ainda continua no coração! Mas já comecei o refresh...

Abraços,
Fabricio]]></content:encoded>
    </item>
    <item>
      <title>Treinamento de Big Data</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/treinamento-de-big-data</link>
      <pubDate>Fri, 03 Aug 2018 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4975</guid>
      <description><![CDATA[Final de semana passada fui no treinamento do Luan Moreno para saber um pouco mais de Big Data. Fui...]]></description>
      <content:encoded><![CDATA[<p>Final de semana passada fui no treinamento do <a href="https://luanmorenodba.com/">Luan Moreno</a> para saber um pouco mais de Big Data. Fui surpreendido! Eis aqui o meu resumo do curso: (note que retirei os nomes e deixei somente a parte das imagens – igual a aqueles jogos de adivinhar o logo)</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/08/image4.png"><img width="1024" height="591" title="image" style="border: 0px currentcolor" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/08/image_thumb4.png" border="0"></a></p><p>Como que o Luan consegue falar tanta coisa em tão pouco tempo???</p><p>O curso começa dando uma visão geral sobre os conceitos (Cloud e Big Data), sendo que logo no primeiro dia já somos apresentados ao universo de produtos disponíveis. O segundo dia foi quase que uma imersão no mundo Hadoop com foco em Batch processing. Por fim, no terceiro dia tivemos Streaming e transferência de dados. </p><p>Valeu a pena participar do curso. Mesmo já conhecendo a maioria dessas ferramentas, o Luan consegue transmitir um conhecimento que não está escrito em livros. </p><p>Por exemplo, quando ele explica HDFS.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/08/image5.png"><img width="293" height="254" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/08/image_thumb5.png" border="0"></a></p><p>Assim como o cenário de IoT:</p><p><a href="https://msdnshared.blob.core.windows.net/media/2018/08/image6.png"><img width="244" height="216" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/08/image_thumb6.png" border="0"></a></p><p>O treinamento abriu minha cabeça ao mostrar que há uma mudança de paradigma no profissional. Não existe como ser especialista em uma única tecnologia. Há muitos produtos ou muitas mudanças, por isso, não da tempo de aprender tudo.</p><p>Recentemente tenho trabalhado com Azure e a situação não é diferente:</p><p><a href="https://github.com/fcatae/SqlBlogNinja/raw/master/files/Microsoft%20Big%20Data%20and%20Data%20Warehousing%20Infographic.pdf"><img width="1024" height="676" title="image" style="border: 0px currentcolor" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/08/image7.png" border="0"></a></p><p>Além do conhecimento adquirido e das reflexões pós-curso, foi ótimo conhecer novas pessoas e reencontrar alguns amigos. </p>]]></content:encoded>
    </item>
    <item>
      <title>Exceptions: Sempre use try-finally</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/exceptions-sempre-use-try-finally</link>
      <pubDate>Thu, 03 Aug 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4887</guid>
      <description><![CDATA[A interface IDisposable e try-finally tem uma relação muito próxima.IDisposable é uma interface que...]]></description>
      <content:encoded><![CDATA[<p>A interface <strong>IDisposable</strong> e <strong>try-finally</strong> tem uma relação muito próxima.<p><strong>IDisposable</strong> é uma interface que implementa o método <strong>Dispose</strong>, que realiza a limpeza dos recursos de forma determinística. Normalmente esse método é chamado dentro de um bloco <strong>finally</strong>.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image39.png"><img width="424" height="255" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb38.png" border="0"></a></p><p>Existe a forma equivalente de chamar o <strong>Dispose </strong>através do <strong>using</strong>.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image40.png"><img width="400" height="118" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb39.png" border="0"></a></p><p>A regra é simples: se o objeto implementa a interface <strong>IDisposable</strong> e possui o método <strong>Dispose</strong>, então use <strong>try-finally</strong> ou <strong>using</strong>. Alguns exemplos importantes de objetos que devem ser limpos: <ul><li><strong>Banco de dados:</strong> <em>SqlConnection e DataReader</em></li><li><strong>Arquivos:</strong> <em>StreamWriter, StreamReader, FileStream</em></li></ul><p>No <a href="https://blogs.msdn.microsoft.com/fcatae/2017/08/02/exceptions-the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/">último artigo</a>, mostrei um exemplo de um erro muito comum: “<em>The timeout period elapsed prior to obtaining a connection from the pool</em>”. Esse erro ocorre porque as conexões não são fechadas corretamente e ficam aguardando para serem finalizadas pela <strong>Finalizer thread</strong>. <p>A solução apresentada foi:<p><img alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb23.png"><p>No entanto, o código não está 100% correto. Note que o objeto <strong>SqlCommand</strong> também implementa a interface <strong>IDisposable</strong> e, portanto, a solução ideal seria:<p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image41.png"><img width="615" height="232" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb40.png" border="0"></a><p>Embora o <strong>SqlCommand </strong>use somente recursos gerenciados, essa escrita tem a vantagem de chamar o <strong>GC.SupressFinalize</strong> contra o objeto, evitando adicionar o objeto à fila de finalização.<h3>Implementando o IDisposable</h3><p>Existem casos que precisamos implementar a interface <strong>IDisposable </strong>na nossa classe. Por exemplo, quando alocamos um objeto Disposable e armazenamos em uma variável membro.<p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image42.png"><img width="399" height="252" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb41.png" border="0"></a><p>O código acima está incorreto. Ninguém chama o método <strong>Dispose</strong> do <strong>SqlConnection</strong>, portanto, a conexão fica aberta e será fechada pela <strong>Finalizer Thread </strong>em um momento posterior (normalmente logo depois de um Garbage Collection). <p>O correto é implementar a interface IDisposable para permitir a limpeza de recursos:<p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image43.png"><img width="452" height="436" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb42.png" border="0"></a><p>Encontrei uma discussão muito boa sobre o IDisposable no Stack Overflow.<blockquote><p>Proper use of the IDisposable interface<br><a title="https://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface" href="https://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface">https://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface</a></p></blockquote><p>Vou aproveitar um dos exemplos (reescrevi o código) para mostrar uma situação que NÃO devemos usar o <strong>IDisposable</strong>. A pergunta inicial é se a classe <strong>MyCollection</strong> deve implementar o método <strong>Dispose</strong> para agilizar a limpeza de memória. A resposta é NÃO para memória gerenciada.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image44.png"><img width="581" height="394" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb43.png" border="0"></a></p><p>O objetivo do método <strong>Dispose</strong> é realizar a limpeza determinística de recursos não-gerenciados e objetos <strong>IDisposable</strong>. No exemplo anterior, a classe <strong>MyCollection</strong> possui a variável membro do tipo <strong>List&lt;String&gt;,</strong> que não é <strong>IDisposable</strong>.<p><br><h3>Conclusão</h3><p>Nesse artigo comentei sobre a interface <strong>IDisposable</strong> e sua relação próxima com o <strong>try-finally</strong>. Infelizmente esse é um tema que ninguém presta atenção. Já vi pessoas defendendo o <a href="https://blogs.msdn.microsoft.com/fcatae/2017/08/01/cuidado-com-o-gc-collect/">uso do GC.Collect no código para garantir performance</a>! Não tenho dúvida de que esquecer de chamar o método <strong>Dispose </strong>é um dos erros mais comuns de programação C#.<p>A regra é sempre usar <strong>try-finally </strong>ou <strong>using </strong>nos objetos <strong>Disposable</strong>.]]></content:encoded>
    </item>
    <item>
      <title>Exceptions: The timeout period elapsed prior to obtaining a connection from the pool</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/exceptions-the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool</link>
      <pubDate>Wed, 02 Aug 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4795</guid>
      <description><![CDATA[Use try-finally para resolver seu problema de “The timeout period elapsed prior to obtaining a...]]></description>
      <content:encoded><![CDATA[<p>Use <strong>try-finally</strong> para resolver seu problema de “<em>The timeout period elapsed prior to obtaining a connection from the pool</em>”. </p><p>Já comentei nos artigos anteriores sobre as construções:</p><ul><li><a href="https://blogs.msdn.microsoft.com/fcatae/2017/07/25/exceptions-evite-o-try-catch/">try-catch</a></li><li><a href="https://blogs.msdn.microsoft.com/fcatae/2017/07/24/exceptions-nao-use-try-catch-finally/">try-catch-finally</a></li></ul><p>Dessa vez vou falar quando usar o try-finally.</p><h3>Exemplo</h3><p>Criei um programa que executa uma Stored Procedure no SQL Server. A versão é bastante simplificada, mas ela tem um erro grave. Procure o problema no código abaixo.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image19.png"><img width="568" height="296" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb19.png" border="0"></a></p><p>Observe que, apesar do erro, o código funciona normalmente.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image20.png"><img width="260" height="94" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb20.png" border="0"></a></p><p>Encontrou o trecho incorreto?</p><h3>Problema</h3><p>Quando codificamos, sempre pensamos no “<em>caminho feliz</em>”, quando tudo dá certo. Entretanto, é possível que determinados comandos falhem. Por exemplo, o método <strong>cmd.ExecuteNonQuery </strong>pode gerar exceções por diversos motivos: comando inexistente, acesso negado, timeout.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image21.png"><img width="561" height="295" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb21.png" border="0"></a></p><p>Se houver uma <strong>SqlException</strong> durante a execução desse comando, a conexão não será fechada. Isso significa que a conexão aberta pelo método <strong>conn.Open</strong> não será encerrada por <strong>conn.Close</strong>. </p><p>Repetimos essa operação 100 vezes e temos a seguinte mensagem:</p><blockquote><p>Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.</p></blockquote><p>Esse erro não é novo. Já havia comentado antes:</p><blockquote><p><a title="https://blogs.msdn.microsoft.com/fcatae/2013/12/09/the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/" href="https://blogs.msdn.microsoft.com/fcatae/2013/12/09/the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/">https://blogs.msdn.microsoft.com/fcatae/2013/12/09/the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/</a></p></blockquote><h3>Sempre use try-finally</h3><p>A forma correta de escrever esse código seria:</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image22.png"><img width="582" height="418" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb22.png" border="0"></a></p><p>Um atalho seria usar a sintaxe <strong>using</strong>:</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/08/image23.png"><img width="627" height="296" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/08/image_thumb23.png" border="0"></a></p><p>Nesse caso, o método <strong>Dispose</strong> é automaticamente chamado e fecha a conexão correspondente.</p><p><br></p><h3>Conclusão</h3><p>Se você recebeu o erro “<em>Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached</em>”, então a causa mais provável é que esqueceu de fazer o <strong>Dispose</strong> do objeto <strong>SqlConnection</strong>.</p><p>Note que eu poderia ter usado <strong>try-finally</strong> ou <strong>using</strong> para o objeto <strong>SqlCommand</strong>. Por que usar ou não usar? Deixarei isso para um próximo artigo.</p>]]></content:encoded>
    </item>
    <item>
      <title>Cuidado com o GC.Collect</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/cuidado-com-o-gc-collect</link>
      <pubDate>Tue, 01 Aug 2017 11:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4705</guid>
      <description><![CDATA[Você já usou o comando GC.Collect? Há inúmeros casos que esse comando resolve problemas de memory...]]></description>
      <content:encoded><![CDATA[Você já usou o comando <strong>GC.Collect</strong>? Há inúmeros casos que esse comando resolve problemas de memory leak.

Entretanto, esse procedimento é somente uma solução temporária e não resolve a real causa raiz. Pense: se o <strong>Garbage Collector (GC)</strong> do .NET faz a limpeza automática de memória, então por que rodá-lo manualmente?

Nesse artigo, vou abordar 3 pontos: <strong>Memory leak, Unmanaged code, Finalizers</strong>. Depois explico qual a relação com o <strong>GC</strong>.
<h3>Memory Leak</h3>
No C/C++, a memória alocada deve ser liberada posteriormente:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image472.png"><img width="324" height="261" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb388.png" border="0" /></a>

A possibilidade de memory leak (vazamento de memória) existe quando o programador deixa de chamar a função de <strong>free/delete </strong>correspondente ao bloco de memória.

Diferente do C/C++, consideramos o .NET como código gerenciado (managed code), pois não existe a necessidade de liberar explicitamente a memória. Não existe <strong>free </strong>ou <strong>delete</strong>. Podemos fazer alocações de memória sem nos preocuparmos com a forma de desalocação, pois toda “memória gerenciada” é liberada automaticamente pelo <strong>Garbage Collector</strong>. Isso diminui os riscos de memory leak.

Ainda fica a pergunta: por que rodar o <strong>GC.Collect </strong>manualmente em .NET?
<h3>Unmanaged Code</h3>
Você pode escrever um programa 100% em C#, mas sempre haverá trechos do runtime que dependem de recursos não-gerenciados. Por exemplo, veja os trechos abaixos:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image473.png"><img width="500" height="113" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb389.png" border="0" /></a>

<strong>StreamReader </strong>e <strong>SqlConnection </strong>são objetos gerenciado e, portanto, o GC faz a limpeza da memória associada. Entretanto, esses objetos usam recursos nativos do Sistema Operacional. No Windows, <strong>StreamReader </strong>possui uma referência a um handle de arquivo, porque internamente ele chama as funções do <strong>CreateFileEx </strong>do <strong>Kernel32.dll</strong>. De forma semelhante, o <strong>SqlConnection </strong>faz referência a uma DLL nativa (escrita em C++), que por sua vez abre sockets TCP via <strong>WinSock2</strong>.

Portanto, ambos os objetos dependem de recursos nativos e não-gerenciados, que não são da responsabilidade do <strong>Garbage Collector</strong>.
<h3>Finalizers</h3>
Os objetos do .NET possuem destrutores denominados de <strong>Finalizers</strong>. Esses métodos são chamados antes do Garbage Collector e são responsáveis por liberar a memória não-gerenciada relacionado ao <strong>unmanged code</strong>.
<blockquote>System.Object: Finalize method
<a href="https://msdn.microsoft.com/en-us/library/system.object.finalize" title="https://msdn.microsoft.com/en-us/library/system.object.finalize">https://msdn.microsoft.com/en-us/library/system.object.finalize</a>

Finalizers (C# programming guide)
<a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors" title="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors">https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors</a></blockquote>
O conceito de destrutor no C++ é bem conhecido. Sempre quando um objeto é desalocado, o destrutor é chamado e depois a memória é devolvida.

Entretanto, o comportamento no C# é ligeiramente diferente. O método Finalize roda em uma thread dedicada chamada de <strong>Finalizer Thread</strong> e não ocorre de forma determinística. Existe inclusive uma lista de objetos a serem finalizados:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image474.png"><img width="639" height="277" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb390.png" border="0" /></a>

Somente objetos que possuem recursos <span style="text-decoration: underline">não-gerenciados</span> entram na fila.

É importante lembrar que o <strong>Garbage Collector (GC) </strong>e a <strong>Finalizer Thread </strong>trabalham em paralelo. Ambos são não-determinísticos, ou seja, não é possível determinar o momento em que rodam. Entretanto, existe uma ordem: a remoção do objeto pelo GC ocorre somente depois de sua finalização.

Em muitos casos, os "problemas de memory leaks do .NET" estão associados a uma longa fila de finalização. Enquanto a thread de finalização está suspensa, essa fila pode crescer e aumentar o consumo de recursos não-gerenciados.
<h3>Conclusão</h3>
A conclusão é que o <strong>GC.Collect</strong> resolve o problema de <strong>memory leak </strong>associado com <strong>unmanaged resource/code</strong>, que não passou ainda pelo <strong>finalizer</strong>.

Portanto, o memory leak ocorre somente nessas condições:
<ul>
 	<li>Garbage collector mantém os objetos com finalização pendente</li>
 	<li>Objetos são finalizados de forma não-determinística (e pode demorar)</li>
 	<li>A fila de finalização cresce em número de objetos e causa o esgotamento de recurso</li>
</ul>
A solução é que normalmente adotar o <strong>Dispose pattern</strong>. Isso significa que os recursos não-gerenciados podem ser liberados de forma determinística através do método <strong>Dispose </strong>do objeto.

Assim como citado no exemplo anterior, os objetos <strong>StreamReader </strong>e <strong>SqlConnection </strong>possuem recursos nativos e que devem ser desalocados manualmente. Embora o finalizer da classe faça a liberação desses recursos, o ideal é sempre chamar o método <strong>Dispose</strong> depois de usar o objeto.

Nos próximos artigos, vou falar sobre o uso do <strong>try-finally</strong> para garantir que os recursos sejam sempre desalocados.]]></content:encoded>
    </item>
    <item>
      <title>Deploy do ambiente de Staging</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/deploy-do-ambiente-de-staging</link>
      <pubDate>Mon, 31 Jul 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4295</guid>
      <description><![CDATA[Esse é um artigo rápido para falar de recursos úteis do WebApp: Integração contínua com...]]></description>
      <content:encoded><![CDATA[<p>Esse é um artigo rápido para falar de recursos úteis do WebApp: </p><ul><li>Integração contínua com GitHub</li><li>Console administrativa com linha de comando</li><li>Monitoração proativa do Application Insight</li></ul><p>Configuramos a aplicação Web em apenas 5 minutos no Azure App Services.</p><h3>Web App</h3><p>No portal do Azure, há um dashboard com as principais métricas de requisições, throughput de dados, tempo de resposta e outras métricas pertinentes a servidores Web. Esse é o ponto de partida para a configuração da aplicação.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image190.png"><img width="629" height="408" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb173.png" border="0"></a></p><p>É possível escolher quais frameworks serão pré-instalados na imagem: .NET, php, Java, Python. No momento, estamos trabalhando com a versão do .NET Core, mas estamos avaliando voltar o uso do .NET Framework 4.6 para agilizar os deployments.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image201.png"><img width="420" height="262" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb174.png" border="0"></a></p><p>A aba de “app settings” permite configurar as variáveis de configuração específicas por ambiente. </p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image202.png"><img width="977" height="301" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb175.png" border="0"></a></p><p>Nessa seção, portanto, configuramos a connection string com os bancos de dados e com as credenciais do Redis. </p><h3>Integração Contínua</h3><p>A melhor funcionalidade do WebApp é a configuração de deployment, que faz a integração contínua com o Git e deployment para o ambiente. Esse recurso de CI/CD pode ser habilitado em menos de 1 minuto!</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image203.png"><img width="853" height="595" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb176.png" border="0"></a></p><p>Note que os deployments correspondem aos commits realizados no repositório.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image204.png"><img width="1134" height="624" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb177.png" border="0"></a></p><p>Existe integração nativa com o GitHub, BitBucket e VSTS. </p><h3>Console Administrativo</h3><p>O servidor de WebApp possui um console administrativo rodando na mesma máquina.</p><blockquote><p>Site: <a href="http://&lt;nome_do_site&gt;.azurewebsites.net">http://&lt;nome_do_site&gt;.azurewebsites.net</a></p><p>Admin: <a href="https://&lt;nome_do_site&gt;.scm.azurewebsites.net">https://&lt;nome_do_site&gt;.scm.azurewebsites.net</a></p></blockquote><p>Esse site administrativo, conhecido também como Kodu, roda somente em HTTPS e requer autenticação. </p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image205.png"><img width="1197" height="388" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb178.png" border="0"></a></p><p>Uma vez logado é possível listar todos os processos ativos na máquina.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image206.png"><img width="855" height="498" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb179.png" border="0"></a></p><p>É possível usar o terminal do CMD ou Powershell para navegar nos diretórios.</p><h3>Monitoração Proativa do Application Insight</h3><p>Fizemos a monitoração do aplicativo usando as ferramentas do Application Insight. Colocamos alguns gráficos no nosso dashboard inicial do Azure para acompanhar o desempenho.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image207.png"><img width="552" height="706" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb180.png" border="0"></a></p><p>Um dos recursos mais legais do Application Insight são as notificações por email. Em uma delas, tenho um resumo semanal da quantidade de acesso e uma comparação com a semana anterior.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image208.png"><img width="699" height="433" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb181.png" border="0"></a></p><p>Há uma notificação proativa para detectar erros e problemas. Em alguns momentos, recebemos alertas avisando sobre um aumento de carga ou degradação do desempenho de uma determinada requisição. </p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb311.png"><img width="615" height="338" title="image_thumb[3][1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb[3][1]" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb31_thumb.png" border="0"></a></p><p>No portal do Application Insight, existem uma série de alertas que podem ser configurados.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb1110.png"><img width="575" height="318" title="image_thumb[1][1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb[1][1]" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb11_thumb.png" border="0"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Exceptions: Evite o try-catch</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/exceptions-evite-o-try-catch</link>
      <pubDate>Tue, 25 Jul 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4636</guid>
      <description><![CDATA[Nesse artigo vou falar para evitar o uso do try-catch e try-catch-finally. No artigo anterior sobre...]]></description>
      <content:encoded><![CDATA[<p>Nesse artigo vou falar para evitar o uso do <strong>try-catch</strong> e <strong>try-catch-finally</strong>. <p>No artigo <a href="https://blogs.msdn.microsoft.com/fcatae/2017/07/24/exceptions-nao-use-try-catch-finally/">anterior sobre try-catch-finally</a>, comentei sobre o tratamento de exceptions usando o <strong>try-catch</strong> ao invés de <strong>try-catch-finally</strong>. <p>Pense duas vezes antes de adicionar um bloco de <strong>catch </strong>para capturar o erro. <p>Na dúvida, evite o uso do <strong>try-catch</strong>.<h3>O que é uma Exception?</h3><p>Uma <strong>Exception </strong>corresponde a uma situação de exceção, que não deveria acontecer em situações normais. Veja esses exemplos:<ul><li>Chipset pegando fogo porque a máquina está operando no deserto</li><li>Placa de memória em curto circuito por causa de uma chuva inundando o data center</li><li>Sistema operacional escrevendo aleatoriamente no disco por conta de um ransomware</li></ul><p>Esses foram exemplos exagerados de exceções que podem acontecer. Por que você faria o tratamento de erro? Afinal, o que você pode fazer em um bloco <strong>try-catch </strong>quando nem a CPU ou a memória RAM funciona direito? </p><p>Entretanto, existem situações de Exception que encontramos no dia a dia:</p><ul><li>Stack overflow</li><li>Falta de memória</li><li>Kernel panic</li></ul><p>Novamente, por que fazer um <strong>try-catch</strong>? O ideal é deixar que o processo falhe completamente e seja reiniciado do zero. Esse é o chamado processo de <em>fail fast</em>: ao encontrar uma situação inesperada, o processo reinicia ao invés de tentar tratar o problema.</p><p>Portanto, evite o uso do <strong>try-catch</strong> e prefira o <em>fail-fast</em>.</p><h3>Engolindo Exceptions</h3><p>Não engula exceções. Em inglês seria “DO NOT swallow exceptions”.</p><p>No nosso código do ARDA, temos um problema reportado pelo <a href="https://github.com/lucaslra">@lucaslra</a>:</p><h4>Issue #4 - Hidden Exceptions</h4><p><a title="https://github.com/DXBrazil/Arda/issues/4" href="https://github.com/DXBrazil/Arda/issues/4">https://github.com/DXBrazil/Arda/issues/4</a></p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image392.png"><img width="859" height="263" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb340.png" border="0"></a></p><p>Imagine a situação de falta de memória ou algo mais crítico. “Engolir a exceção” e retornar valores nulos não vai ajudar em nada. Existem algumas opções para tratamento (ex: gravar em um log), mas minha sugestão é sempre evitar o <strong>try-catch</strong>.</p><h3>Tratamento de Exceção</h3><p>A correção para o problema reportado foi remover o <strong>try-catch</strong>. Veja o trecho original abaixo:</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image393.png"><img width="541" height="567" title="image" style="border: 0px currentcolor" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb341.png" border="0"><br></a><a title="https://github.com/DXBrazil/Arda/blob/771695ec90b651098f43dd6296930682a285fd5f/src/Arda.Kanban/Controllers/ActivityController.cs" href="https://github.com/DXBrazil/Arda/blob/771695ec90b651098f43dd6296930682a285fd5f/src/Arda.Kanban/Controllers/ActivityController.cs">https://github.com/DXBrazil/Arda/blob/771695ec90b651098f43dd6296930682a285fd5f/src/Arda.Kanban/Controllers/ActivityController.cs</a></p><p>Esse código é ruim porque “engole a exception”: a requisição retorna o status <strong>HTTP 200 (sucesso) </strong>com conteúdo nulo (No content).</p><p>Compare com a versão sem <strong>try-catch</strong>, que simplifica a lógica:</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image394.png"><img width="474" height="220" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb342.png" border="0"></a><br><a title="https://github.com/DXBrazil/Arda/blob/2c9e79f84f1e00a3c75d5e4964bd8a28bc834318/src/Arda.Kanban/Controllers/ActivityController.cs" href="https://github.com/DXBrazil/Arda/blob/2c9e79f84f1e00a3c75d5e4964bd8a28bc834318/src/Arda.Kanban/Controllers/ActivityController.cs">https://github.com/DXBrazil/Arda/blob/2c9e79f84f1e00a3c75d5e4964bd8a28bc834318/src/Arda.Kanban/Controllers/ActivityController.cs</a></p><p>Se uma exceção acontecer, um midlleware do ASP.NET intercepta a Exception e transforma em uma resposta <strong>HTTP 500 (erro interno)</strong>. Acredito que o status <strong>HTTP 500</strong> é mais adequado que o <strong>HTTP 200</strong>.<h3>Usando Try-Catch em Console Application</h3><p>Uma exception não tratada força o cancelamento da thread que, por sua vez, pode derrubar o processo inteiro. Portanto, existem casos que queremos evitar que uma exception cancele o processo inteiro. </p><p>Nesse caso, voce deve usar um <strong>try-catch</strong> no método estático <strong>Main</strong> do arquivo <strong>Program.cs</strong>.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image395.png"><img width="576" height="329" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb343.png" border="0"></a><p>Note que estou sendo bastante específico com relação ao <strong>try-catch</strong>: dentro do método <strong>Main </strong>do <strong>Program.cs</strong>. Em qualquer outra situação, recomendo que pense duas vezes.<h3>Quando usar try-catch</h3><p>Infelizmente ainda existem casos que precisam do <strong>try-catch</strong>: determinados trechos do código não devem disparar Exceptions e, por isso, devemos adicionar um bloco de tratamento de erro. </p><p>Um exemplo é o ARDA, que acessa dados do SQL Server e mantém um cache no Redis. Quando o serviço do RedisCache fica indisponível, a requisição deve ignorar o cache e consultar diretamente ao banco de dados. No nosso caso, implementamos um <strong>try-catch </strong>especificando a captura somente da exceção <strong>RedisConnectionException</strong>.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image396.png"><img width="798" height="424" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb344.png" border="0"></a><br><a title="https://github.com/DXBrazil/Arda/blob/0dcc8f283d52e85d3ba47f3529ffb0fa9f06c93b/src/Arda.Permissions/Repositories/PermissionRepository.cs" href="https://github.com/DXBrazil/Arda/blob/0dcc8f283d52e85d3ba47f3529ffb0fa9f06c93b/src/Arda.Permissions/Repositories/PermissionRepository.cs">https://github.com/DXBrazil/Arda/blob/0dcc8f283d52e85d3ba47f3529ffb0fa9f06c93b/src/Arda.Permissions/Repositories/PermissionRepository.cs</a></p><p>Nesse caso, usamos o <strong>try-catch</strong> para evitar que a falha do Cache impacte na disponibilidade do serviço. O mais importante é que somos bastante específico com relação ao tipo de exceção, pois não é a genérica <strong>System.Exception</strong>.</p><p><p><h3>Usando Try-Catch no ASP.NET</h3><p>Se você usa o ASP.NET, então não há motivo para usar <strong>try-catch </strong>porque o middleware faz esse trabalho por você. Observamos isso ao longo do trabalho com o ARDA, quando limpamos os <strong>try-catch </strong>do código.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image397.png"><img width="646" height="164" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb345.png" border="0"></a><br><a title="https://github.com/DXBrazil/Arda/issues/4" href="https://github.com/DXBrazil/Arda/issues/4">https://github.com/DXBrazil/Arda/issues/4</a></p><p>Entretanto, veja que ainda há casos importantes de <strong>try-catch </strong>que devem ser mantidos.</p><p><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image398.png"><img width="644" height="209" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb346.png" border="0"></a></p><p>Na grande maioria dos casos, usamos <strong>try-catch </strong>com exceções específicas.</p><blockquote><p>Check transient errors (RedisConnectionException)<br><a title="https://github.com/DXBrazil/Arda/commit/b10a4fcf9f68001b7f2f2f92974ad3b4802a3d71" href="https://github.com/DXBrazil/Arda/commit/b10a4fcf9f68001b7f2f2f92974ad3b4802a3d71">https://github.com/DXBrazil/Arda/commit/b10a4fcf9f68001b7f2f2f92974ad3b4802a3d71</a></p><p>Removed try/catch from VerifyUserAccessToResource exception<br><a title="https://github.com/DXBrazil/Arda/commit/229acae260ce727a2cf7f9aa4eb389c73b00dbaa" href="https://github.com/DXBrazil/Arda/commit/229acae260ce727a2cf7f9aa4eb389c73b00dbaa">https://github.com/DXBrazil/Arda/commit/229acae260ce727a2cf7f9aa4eb389c73b00dbaa</a></p><p>Catch RedisConnectionException thrown in GetUserMenuSerialized<br><a title="https://github.com/DXBrazil/Arda/commit/b3eb3c2c2a40d0aff3352b15278528ff62aedfe9" href="https://github.com/DXBrazil/Arda/commit/b3eb3c2c2a40d0aff3352b15278528ff62aedfe9">https://github.com/DXBrazil/Arda/commit/b3eb3c2c2a40d0aff3352b15278528ff62aedfe9</a></p><p>Remove generic exceptions from GetUserPhoto<br><a title="https://github.com/DXBrazil/Arda/commit/d4555d22021dc05a18ca0f6a222293498a6fb863" href="https://github.com/DXBrazil/Arda/commit/d4555d22021dc05a18ca0f6a222293498a6fb863">https://github.com/DXBrazil/Arda/commit/d4555d22021dc05a18ca0f6a222293498a6fb863</a></p><p>Remove unused function CallMicrosoftGraph<br><a title="https://github.com/DXBrazil/Arda/commit/84b1086a0f828e004fbae94496e87e059da635eb" href="https://github.com/DXBrazil/Arda/commit/84b1086a0f828e004fbae94496e87e059da635eb">https://github.com/DXBrazil/Arda/commit/84b1086a0f828e004fbae94496e87e059da635eb</a></p></blockquote><p><br></p><h3>Conclusão</h3><p>Nesse artigo, falei que minhas regras com relação ao <strong>try-catch </strong>são:</p><ol><li>Na dúvida, evite o uso do <strong>try-catch </strong></li><li>Use no <strong>Program.cs </strong>para evitar o crash do processo</li><li>Se for necessário tratar a exceção, especifique o tipo de exceção</li></ol><p>Na dúvida, pense no <em>fail-fast </em>e evite “<em>engolir exceptions</em>”.</p>]]></content:encoded>
    </item>
    <item>
      <title>Exceptions: Não use try-catch-finally</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/exceptions-nao-use-try-catch-finally</link>
      <pubDate>Mon, 24 Jul 2017 13:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4385</guid>
      <description><![CDATA[Essa semana estava revendo um trecho do ARDA (https://github.com/DXBrazil/Arda) e os primeiros...]]></description>
      <content:encoded><![CDATA[Essa semana estava revendo um trecho do ARDA (<a href="https://github.com/DXBrazil/Arda" title="https://github.com/DXBrazil/Arda">https://github.com/DXBrazil/Arda</a>) e os primeiros issues e pull requests estavam relacionados com o tratamento de exceção. Por coincidência, nessa mesma semana, fui perguntado sobre as melhores práticas de Exceptions sobre como e quando usar.

Comecei olhando a documentação do C# sobre o <strong>try-catch-finally</strong>.
<blockquote>Try-catch-finally
<a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch-finally">https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch-finally</a></blockquote>
Nesse artigo, há o seguinte trecho de código:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image372.png"><img width="682" height="327" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb324.png" border="0" /></a>

Então, pergunto:
<blockquote>O que há de errado nesse exemplo?</blockquote>
Embora a linguagem permita a construção e a documentação confirma que é possível, sigo o pensamento de que a sintaxe try..catch..finally não deveria existir no C#. Na minha opinião, <strong>não se deve usar try-catch-finally</strong>. Essa é uma afirmação forte e, antes de que alguém se desespere, deixo explicar meu ponto de vista.
<h3>Por que não existe “finally” no C++?</h3>
Você sabia que a linguagem C++ suporta exceções e somente a construção <strong>try-catch</strong>? Não existe <strong>finally</strong>!
<blockquote><a href="http://www.stroustrup.com/bs_faq2.html#finally">http://www.stroustrup.com/bs_faq2.html#finally</a>
Why doesn't C++ provide a "finally" construct?</blockquote>
Resposta do Bjarne Stroustrup:
<blockquote>Because C++ supports an alternative that is almost always better: The "resource acquisition is initialization" technique (TC++PL3 section 14.4).</blockquote>
A linguagem do C++ adota o padrão de <strong>Resource Acquisition is Initialization (RAII)</strong>. Em outras palavras, os recursos devem ser desalocados dentro do destrutor das classes, dispensando o uso do <strong>finally</strong>.
<h3>Use try-catch</h3>
Quando lidamos com exceção, tratamos as exceptions através de blocos <strong>try-catch</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image373.png"><img width="420" height="191" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb325.png" border="0" /></a>

<a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch" title="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch">https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch</a>

Não tem segredo: as exceções são capturadas pelo bloco <strong>catch</strong> para tratamento do erro.
<h3>Use try-finally</h3>
A linguagem suporta a construção <strong>try-finally </strong>para liberar os recursos alocados.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image374.png"><img width="408" height="217" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb326.png" border="0" /></a>

<a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally" title="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally">https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally</a>

Diferente do C++, o garbage collector do C# (.NET) é não-determinístico. Por isso, sempre garanta que os recursos são liberados no momento certo através do <strong>finally</strong>.
<h3>Não use try-catch-finally</h3>
A construção <strong>try-catch-finally </strong>mistura dois propósitos distintos no mesmo código. Por isso, deixe claro a intenção e use a sintaxe adequada com os blocos:
<ul>
 	<li><strong>try-catch:</strong> Tratar os erros e exceções</li>
 	<li><strong>try-finally: </strong>Liberar explicitamente os recursos</li>
</ul>
Reescrevi o trecho anterior usando <strong>try-catch-finally</strong> e, ao invés de melhorar o código, parece que ficou mais confuso:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image375.png"><img width="781" height="450" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb327.png" border="0" /></a>

Nesse momento, é natural encapsular o trecho do código de leitura de arquivo dentro de outra função. Veja como o código fica mais claro:

<strong><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image376.png"><img width="809" height="260" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb328.png" border="0" /></a></strong>

A função ReadFileBlock gerencia o objeto File, fazendo a alocação de recurso e liberando no <strong>finally</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image387.png"><img width="796" height="339" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb321.png" border="0" /></a>

Compare como ficou muito melhor que a versão <strong>try-catch-finally</strong>.

&nbsp;
<h3>Conclusão</h3>
Nesse artigo, apresentei a ideia de evitar o <strong>try-catch-finally </strong>porque essa construção mistura os conceitos de tratamento de exceção e liberação de recurso. Ao invés disso, recomendo que use <strong>try-catch </strong>ou <strong>try-finally</strong>.]]></content:encoded>
    </item>
    <item>
      <title>Bots, Devops e Docker</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/bots-devops-e-docker</link>
      <pubDate>Thu, 20 Jul 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=4485</guid>
      <description><![CDATA[Participamos de um Hackathon de Bots.
Whitepaper: Bots, DevOps e Docker - Lições aprendidas em 48...]]></description>
      <content:encoded><![CDATA[Participamos de um Hackathon de Bots.
<blockquote>Whitepaper: Bots, DevOps e Docker - Lições aprendidas em 48 horas
<a href="https://msdnshared.blob.core.windows.net/media/2017/07/DX-Bots-DevOps-Docker.pdf">[Download do Whitepaper]</a></blockquote>
Já faz quase um ano que nos juntamos para trabalhar em um projeto de Bot. Nosso time era composto por pessoas com diferentes especialidades e, por isso, decidimos empregar as técnicas de DevOps para garantir uma entrega ágil e sem perda de qualidade durante o evento.
<h3>Cockpit da NASA</h3>
Uma coisa é certa: desde o início já sabíamos como seria nosso dashboard. Teria que todos os indicadores de processo, incluindo cada fase do nosso pipeline de entrega (Build, Release e Teste) até o ambiente de produção.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image381.png"><img width="1550" height="856" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb333.png" border="0" /></a>

Construímos um pipeline de entrega para remover os passos manuais dos processos de compilação até a publicação. Todos enxergavam o status do projeto pelo dashboard do VSTS, que fornecia informações sobre:
<ul>
 	<li>Tarefas pendentes</li>
 	<li>Resultado dos builds</li>
 	<li>Distribuição da aplicação</li>
 	<li>Resultado dos testes</li>
 	<li>Monitoração da aplicação e infraestrutura</li>
</ul>
Uma das vantagens da integração contínua no VSTS era a visão do histórico de compilação. Acredite ou não, ver tantos indicadores na cor verde aumentava a nossa confiança, pois sabíamos que estávamos fazendo o trabalho certo. Lógico que, no começo, estava tudo vermelho.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image382.png"><img width="1532" height="707" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb334.png" border="0" /></a>

Em um cenário sem esse acompanhamento detalhado, talvez a gente não estivesse tão confortável em fazer modificações próximos ao final do evento. Você já certamente viu isso acontecer na empresa – o período de freezing. Entretanto, nosso time não teve freezing e seguimos codificando até o último minuto.
<h3>Linux e Containers</h3>
Desde o começo imaginamos criar um projeto para rodar em Linux. Todo o desenvolvimento foi realizado com o Visual Studio 2015 rodando em Windows, porém, utilizamos a versão do .NET Core.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image383.png"><img width="644" height="448" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb335.png" border="0" /></a>

Usamos o Windows e Linux ao mesmo tempo. Isso é confuso?

Começamos configurando os agentes VSTS no Linux para compilar nossos microserviços baseados em ASP.NET Core.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image384.png"><img width="1212" height="450" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb336.png" border="0" /></a>

Nosso ambiente de produção era baseado no Docker:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image385.png"><img width="1337" height="126" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb337.png" border="0" /></a>

Embora pareça apenas um Docker Host, esse ambiente era um cluster de container.
<h4><a href="https://msdnshared.blob.core.windows.net/media/2017/07/image386.png"><img width="594" height="307" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb338.png" border="0" /></a></h4>
Azure Container Services contém um conjunto de máquinas virtuais instalados com o Docker Engine. Quando um container é instanciado, sua execução será direcionada para um dos nós (VMs) deste grupo de agentes. Assim, temos a garantia de alta disponibilidade.
<h3>Bots</h3>
Por fim, faltou falar do nosso projeto. A ideia era criar um Bot para responder dúvidas sobre Azure. No front-end, usamos o Microsoft Bot Framework para conectar o Bot com diferentes canais de comunicação (Skype, SMS, e-mail, etc). No back-end, criamos microserviços de busca rodando em Linux e containers Docker.
<h3>Ganhamos o Hackathon?</h3>
Com tudo isso rodando, não chegamos nem perto de ganhar o Hackathon. Investimos bastante tempo na “engenharia” do projeto e realmente avançamos pouco na inovação do projeto. O time que ganhou combinou uma série de tecnologias: IoT, Machine Learning, PowerBI, e nem me lembro mais o que.

Perdemos o hackaton, mas nem tudo foi em vão. Conseguimos finalizar o projeto do Bot usando as tecnologias propostas inicialmente. Ganhamos muito conhecimento ao longo desses dois dias. Escrevemos um whitepaper sobre o projeto e também aplicamos esse conhecimento em outros projetos (ex: Arda).

Foi um ótimo aprendizado.

&nbsp;
<h3>Conclusão</h3>
O evento foi fantástico e pode ser resumido em 3 pontos:
<ul>
 	<li><strong>Perdemos o hackathon:</strong> Durante um hackathon, o ótimo é inimigo do bom. Se você participar de um, exponha sua ideia da forma mais criativa possível. Esqueça a engenharia nos bastidores do projeto, pois isso não ganha ponto (ninguém vê).</li>
 	<li><strong>Aprendemos DevOps: </strong>Trabalhamos com uma equipe de 2 ITPros e 3 Developers. Vimos na prática como é difícil definir as responsabilidades dentro da equipe, mas conseguimos enxergar o benefício de adotar os processos de Continuous Integration (CI) para Dev e Continuous Delivery (CD) para Infra.</li>
 	<li><strong>DevOps requer investimento:</strong> Dividimos o tempo de 3 desenvolvedores entre código e DevOps. No nosso caso, parece que gastamos 75% em DevOps e apenas 25% codificando. Poderíamos ter investido 100% do tempo em código e ignorado nossa “engenharia em DevOps”. Se você quiser fazer DevOps, então saiba que há um preço a se pagar.</li>
</ul>
Como o evento de Hackathon durou apenas 2 dias (prazo curtíssimo), não conseguimos usufruir dos benefícios do DevOps. Porém, sempre que começamos um projeto, recomendo que haja um investimento de pelo menos 50% em DevOps. Esse tempo aumenta a eficiência dos desenvolvedores e traz retorno em médio e longo prazo.]]></content:encoded>
    </item>
    <item>
      <title>Falha Nossa no Git (TOP 5)</title>
      <link>https://docs.microsoft.com/archive/blogs/fcatae/falha-nossa-no-git-top-5</link>
      <pubDate>Wed, 19 Jul 2017 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Fabricio Catae]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fcatae/?p=3995</guid>
      <description><![CDATA[Fiz aqui um TOP 5 das coisas mais estranhas que notei no nosso repositório do ARDA.

Seguem os...]]></description>
      <content:encoded><![CDATA[Fiz aqui um TOP 5 das coisas mais estranhas que notei no nosso repositório do ARDA.

Seguem os links dos repositórios:
<blockquote>Antigo: <a href="https://github.com/DXBrazil/Arda_old" title="https://github.com/DXBrazil/Arda_old">https://github.com/DXBrazil/Arda_old</a>
Recente: <a href="https://github.com/DXBrazil/Arda">https://github.com/DXBrazil/Arda</a></blockquote>
Bons desenvolvedores mantém o histórico do GIT linear e conciso usando um <strong>workflow definido</strong> <strong>(ex: gitflow)</strong>, <strong>squash commit</strong>, <strong>rebase</strong>, etc. Nosso time é bom, mas ignoramos essas práticas e mantivemos todos os commits intermediários. Felizmente como o histórico ficou intacto, hoje é possível entender a história do ARDA em todos os detalhes, principalmente com os nossos erros.
<h3>Falha #5: Trabalhar sem feature branches</h3>
Por um tempo, mantivemos branches individuais por usuários e isso gerou um histórico visualmente não-linear:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image158.png"><img width="630" height="406" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb136.png" border="0" /></a>

Em nosso projeto, não adotamos o rebase e sempre fizemos pontos de merge. Embora o rebase torne o histórico mais linear, a vantagem do merge é manter o histórico fiel aos commits realizados.

Apenas como brincadeira, peguei um screenshot do SourceTree e rotacionei a imagem, tornando o nosso histórico musicalmente mais interessante:

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image159.png"><img width="638" height="227" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb137.png" border="0" /></a>

Que confusão! Hoje vejo que poderíamos ter feito um histórico mais limpo se tivéssemos adotado o workflow do Gitflow (ou semelhante) desde o princípio do projeto.
<h3>Falha #4: Guardar senhas dentro do repositório</h3>
O pior é que esse erro é muito comum nos projetos. No nosso caso, adicionamos o arquivo de <strong>secrets.json </strong>com informações de login no Redis, SQL Server e Azure Blob Storage.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image160.png"><img width="747" height="162" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb138.png" border="0" /></a>

Em seguida, tentamos remover as senhas com um commit “<strong>removido string de conexão do sql server</strong>”.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image161.png"><img width="698" height="67" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb139.png" border="0" /></a>

Esse commit também poderia ser renomeado para “<strong>hackers, aqui tem senha -- veja os detalhes do commit</strong>”. Embora as senhas sejam removidas dos arquivos, os commits são mantidos dentro do repositório do GIT e qualquer um que tenha acesso pode olhar o histórico do arquivo.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image162.png"><img width="698" height="251" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb140.png" border="0" /></a>

Lição: esse erro sempre vai acontecer e se repetir, então esteja preparado para definir um processo de reset de senhas nos ambientes de desenvolvimento, teste e produção.
<h3>Falha #3: Configurar incorretamente o GIT Client</h3>
Durante a instalação do cliente do Git, você configura um usuário e email para acessar o repositório. Se tiver máquinas diferentes, então deve repetir a configuração em todas as máquinas.

Falhamos nisso. Temos diversos emails registrados:
<ul>
 	<li><a>@microsoft</a></li>
 	<li><a>@hotmail</a></li>
 	<li><a>@live</a></li>
 	<li>[sem domínio]</li>
</ul>
Fabricio Sanchez, por exemplo, usou várias configurações de email diferente:
<ul>
 	<li><a>fabsanc@DESKTOP-GM6LNGT</a></li>
 	<li><a>fabriciosanchez@MacBook-Pro-de-Fabricio.local</a></li>
 	<li><a>fabriciosanchez@mbp-de-fabricio.guest.corp.microsoft.com</a></li>
</ul>
Configurar usuário e email errado tem um impacto muito baixo, mas gerou uma estatística interessante: a contribuição do Fabricio Sanchez foi apagar 165 mil linhas do projeto contra 135 mil adicionadas! Ele destruiu mais do que criou (merece um prêmio hehe).

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image163.png"><img width="411" height="251" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb141.png" border="0" /></a>

Obrigado Fabricio Sanchez por todos os seus deletes no projeto!

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image164.png"><img width="742" height="410" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb142.png" border="0" /></a>

Mas suspeito que, pelo fato de configurar o usuário/email errado, fez com que suas adições fossem ignoradas.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image165.png"><img width="470" height="499" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb143.png" border="0" /></a>

No final, isso não tira o mérito dele em ser um grande contribuidor do projeto ARDA.
<h3>Falha #2: Erro no arquivo Git Ignore</h3>
Outro erro comum é esquecer de configurar o arquivo do Git Ignore (<strong>.gitignore</strong>) e incluir arquivos desnecessários no controle de versão. Entre os casos mais comuns estão os diretórios <strong>bin</strong>, <strong>out</strong>, <strong>obj</strong>,<strong> bower_components</strong>, <strong>node_modules.</strong>
<blockquote>O que há de errado em incluir as dependências do NodeJS (diretório <strong>node_modules</strong>)?</blockquote>
<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image166.png"><img width="261" height="494" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb144.png" border="0" /></a>

Simples: esse diretório tem 7302 arquivos que não precisam estar versionados no Git.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image167.png"><img width="419" height="298" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb145.png" border="0" /></a>

Mas por incrível que pareça, nosso time do ARDA <strong>não </strong>cometeu essa falha!!! O Visual Studio cria automaticamente o arquivo com as extensões a serem ignoradas e, por isso, o <strong>.gitignore </strong>estava correto desde o começo do projeto.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image168.png"><img width="634" height="398" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb146.png" border="0" /></a>

Entretanto, nós fizemos melhor: nosso estagiário (sempre ele!) adicionou o caminho do nosso projeto <strong>Arda.Main</strong> dentro do Git ignore.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image169.png"><img width="552" height="196" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb147.png" border="0" /></a>

Quando você faz isso, erros estranhos acontecem no projeto do Arda.Main:
<ul>
 	<li>Arquivo existentes: continuam “trackeados” pelo git e a atualização funciona</li>
 	<li>Arquivos novos: são ignorados pelo .gitignore e não são incluídos no projeto</li>
</ul>
Esse comportamento gerou erros aleatórios por um bom tempo. Determinadas modificações do Arda.Main funcionavam, outras não. Só fomos descobrir a causa do problema dias depois.
<h3>Falha #1: Falta de controle no master</h3>
Nossos repositórios (GitHub e VSTS) são protegidos por senha, mas qualquer um do time podia entrar no repositório e editar os arquivos. Pela descrição, dá para identificar algumas gambiarras. Por exemplo, <strong>commits </strong>correspondentes a <strong>Work in Progress (WIP) </strong>estão em vários lugares no histórico do Git.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image170.png"><img width="293" height="58" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb148.png" border="0" /></a>

Tem outros commits de “<strong>adjusting dockerfile again</strong>” ou “<strong>once again, trying to adjust the path</strong>” realizados direto na <strong>master</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image171.png"><img width="351" height="72" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb149.png" border="0" /></a>

Isso sem contar que usamos o repositório <strong>master </strong>para demonstrações no Tech Summit 2016.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image172.png"><img width="276" height="52" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb150.png" border="0" /></a>

A coisa fica feia quando aparece um <strong>root</strong> fazendo <strong>commit</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image173.png"><img width="438" height="146" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb151.png" border="0" /></a>

Até hoje não sei de onde veio esse <strong>commit</strong>, mas acho que foi alguém usando o VIM dentro de um Ubuntu para rodar os containers.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/image174.png"><img width="788" height="25" title="image" style="margin: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/07/image_thumb152.png" border="0" /></a>

Entendo que diversas vezes usamos essa aplicação para demonstração em eventos. Entretanto, a nossa branch <strong>master</strong> ficou uma bagunça. Se esse projeto fosse crítico (mais crítico do que é atualmente), a gente deveria fazer Fork do repositório e trabalhar nele. Enfim, várias formas de organizar o acesso aos repositórios.

&nbsp;
<h3>Conclusão</h3>
Seu time realmente sabe trabalhar com o Git?

No nosso caso, estamos (sempre) aprendendo…

E vocês? Compartilhem suas experiências ruins nos comentários - as boas experiências já conhecemos!

&nbsp;]]></content:encoded>
    </item>
  </channel>
</rss>