<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Marcio Althmann</title>
	
	<link>http://www.marcioalthmann.net</link>
	<description />
	<lastBuildDate>Wed, 16 May 2012 04:06:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MarcioFabioAlthmann" /><feedburner:info uri="marciofabioalthmann" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>String.Intern – Evitando duplicação de strings</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/AZHqZBRZ1ZU/</link>
		<comments>http://www.marcioalthmann.net/2012/05/string-intern-evitando-duplicacao-de-strings/#comments</comments>
		<pubDate>Wed, 16 May 2012 01:43:10 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Dicas]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=949</guid>
		<description><![CDATA[Para aproveitar esse artigo, é bom entender o conceito de String Interning ou Tabela de Strings, pode encontrar mais sobre o assundo no meu artigo Entendendo Strings. Esse é o primeiro de uma série de artigos onde vou mostrar algumas dicas, ferramentas e truques para analisar aplicações e identificar problemas, as vezes isso será feito...<p><a href="http://www.marcioalthmann.net/2012/05/string-intern-evitando-duplicacao-de-strings/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Para aproveitar esse artigo, é bom entender o conceito de String Interning ou Tabela de Strings, pode encontrar mais sobre o assundo no meu artigo <a href="http://www.marcioalthmann.net/2011/02/entendendo-strings/" target="_blank">Entendendo Strings</a>.</p>
<p>Esse é o primeiro de uma série de artigos onde vou mostrar algumas dicas, ferramentas e truques para analisar aplicações e identificar problemas, as vezes isso será feito só com o dump de memória da aplicação o que vai deixar o trabalho mais divertido :D.</p>
<p>Voltando ao assunto das Strigs, o que não falei no primeiro artigo, é que essa tabela de strings é montada em tempo de compilação, isso significa que durante a execução do sistema podemos ter strings duplicadas em memória,e no caso de uma aplicação com problemas de consumo de memória, já temos um bom lugar para começar a análise!</p>
<p>Nesse artigo estou utilizando a ferramenta <a href="http://www.yourkit.com/" target="_blank">YourKit Profiler for .NET.</a>.</p>
<p>Veja o código abaixo:</p>
<p><script src="https://gist.github.com/2706357.js"> </script></p>
<p>Nesse código incluímos 1000 vezes a string &#8220;Althmann&#8221; em uma lista, a parte boa é que em tempo de compilação isso será resolvido, e a tabela de strings vai entrar em ação, teremos só 1 &#8220;Althmann&#8221; em memória.</p>
<p>Mas logo abaixo adicionamos na mesma lista, um texto qualquer que o usuário digitar, é aqui que a brincadeira fica divertida. Não temos muito controle do que será informado no sistema, ou de XMLs gigantes carregados, ou seja, quase tudo vira string nos sistemas, e dependendo do tamanho das strings e da sua duplicação o consumo de memória pode ser elevado.</p>
<p>Nesse teste eu vou escrever 10 vezes a seguinte frase.</p>
<p><em><br />
Preciso acabar logo o artigo porque quero jogar Diablo 3<br />
</em></p>
<p>Utilizando o YourKit Profiler, consigo executar facilmente algumas análises de possíveis memory leaks, um dos itens que ele analisa por padrão é a duplicação de strings, veja na imagem abaixo ele mostrando as 10 strings duplicadas em memória.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/05/StringDuplicada01.png" rel="lightbox[949]" title="StringDuplicada01"><img class="aligncenter size-medium wp-image-952" title="StringDuplicada01" src="http://www.marcioalthmann.net/wp-content/uploads/2012/05/StringDuplicada01-300x160.png" alt="" width="300" height="160" /></a></p>
<p>O bom é que a ferramenta já da dicas de possíveis formas de resolver o problema, a que vou utilizar é a String.Intern.</p>
<p>Veja o novo código usando agora <a href="http://msdn.microsoft.com/en-us/library/system.string.intern.aspx" target="_blank">String.Intern</a>.</p>
<p><script src="https://gist.github.com/2706392.js"> </script></p>
<p>Explicando de uma forma simples, quando eu faço <em>String.Intern(Console.ReadLine())</em>, antes de adicionar a string na lista, será feita uma verificação se essa string já está na tabela de strings, se não estiver adiciona e se estiver retorna a referência.</p>
<p>Com isso repetindo novamente a frase anterior 10 vezes o YourKit Profiler não acusa mais a minha frase repetida em memória.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/05/StringDuplicada02.png" rel="lightbox[949]" title="StringDuplicada02"><img class="aligncenter size-medium wp-image-953" title="StringDuplicada02" src="http://www.marcioalthmann.net/wp-content/uploads/2012/05/StringDuplicada02-300x160.png" alt="" width="300" height="160" /></a></p>
<p>Simples e com ótimo resultado, então isso é regra, se eu tenho um consumo elevado de memória vou usar String.Intern?</p>
<p>De forma alguma! Nem tudo são flores, temos que levar em consideração performance, afinal existe uma operação para verificar se essa string já existe, mas ainda farei alguns testes mais sérios para verificar se realmente é um problema. Mais um detalhe, prestem muita atenção no texto abaixo, ao tentar resolver um problema podemos gerar outros ;).</p>
<blockquote><p>
If you are trying to reduce the total amount of memory your application allocates, keep in mind that interning a string has two unwanted side effects. First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. The reason is that the CLR&#8217;s reference to the interned String object can persist after your application, or even your application domain, terminates. Second, to intern a string, you must first create the string. The memory used by the String object must still be allocated, even though the memory will eventually be garbage collected.
</p></blockquote>
<p>Por hoje é isso.</p>
<p>Abraços</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/05/string-intern-evitando-duplicacao-de-strings/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/AZHqZBRZ1ZU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/05/string-intern-evitando-duplicacao-de-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/05/string-intern-evitando-duplicacao-de-strings/</feedburner:origLink></item>
		<item>
		<title>C# – Keywords const e readonly</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/mn_SSnAh2XY/</link>
		<comments>http://www.marcioalthmann.net/2012/05/c-keywords-const-e-readonly/#comments</comments>
		<pubDate>Mon, 14 May 2012 04:08:49 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[const]]></category>
		<category><![CDATA[keywords]]></category>
		<category><![CDATA[readonly]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=946</guid>
		<description><![CDATA[Faz algum tempo que não falo sobre C#, apesar de sempre utilizar C# nos programas, é sempre bom dar mostrar algo da linguagem, apesar de ser um assunto básico, nunca é demais falar sobre algumas keywords. Já escrevi sobre algumas keywords do C# aqui no blog, e hoje vou falar sobre as keywords const e...<p><a href="http://www.marcioalthmann.net/2012/05/c-keywords-const-e-readonly/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Faz algum tempo que não falo sobre C#, apesar de sempre utilizar C# nos programas, é sempre bom dar mostrar algo da linguagem, apesar de ser um assunto básico, nunca é demais falar sobre algumas keywords.</p>
<p>Já escrevi sobre algumas <a href="http://www.marcioalthmann.net/?s=keyword" target="_blank">keywords do C# aqui no blog</a>, e hoje vou falar sobre as keywords <em>const</em> e <em>readonly</em>, que são parecidas mas não iguais ;).</p>
<h1>const</h1>
<p>Com a keyword const, nós definimos que o valor de uma variável ou filtro é constante, ou seja, não pode ser alterado após sua inicialização, e só podemos definir o valor na declaração da variável ou field.</p>
<p><script src="https://gist.github.com/2691702.js"> </script></p>
<h1>readonly</h1>
<p>Diferente da keyword const, com a keyword readonly, podemos utilizá-la apenas em fields, e a definição do valor pode ser feito na sua declaração ou no construtor da classe, tentar declarar o valor de um field readonly em um método da classe por exemplo da erro de compilação.</p>
<p><script src="https://gist.github.com/2691720.js"> </script></p>
<p>Por hoje é só até o próximo post.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/05/c-keywords-const-e-readonly/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/mn_SSnAh2XY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/05/c-keywords-const-e-readonly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/05/c-keywords-const-e-readonly/</feedburner:origLink></item>
		<item>
		<title>RavenDB: DocumentStore e DocumentSession</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/pjQVgV7Sw2g/</link>
		<comments>http://www.marcioalthmann.net/2012/05/ravendb-documentstore-e-documentsession/#comments</comments>
		<pubDate>Fri, 04 May 2012 00:54:48 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[RavenDB]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[ravendb]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=943</guid>
		<description><![CDATA[No primeiro artigo sobre o RavenDB, eu listei algumas características do produto, e para finalizar, mostrei um código simples onde um objeto era incluído no banco de dados. Nesse código existem dois objetos importantes da API do RavenDB, o DocumentStore e o DocumentSession, vamos começar pelo  Store. De uma forma simples, é com o DocumentStore que criamos...<p><a href="http://www.marcioalthmann.net/2012/05/ravendb-documentstore-e-documentsession/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>No <a href="http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/" target="_blank">primeiro artigo</a> sobre o RavenDB, eu listei algumas características do produto, e para finalizar, mostrei um código simples onde um objeto era incluído no banco de dados.</p>
<p>Nesse código existem dois objetos importantes da API do RavenDB, o <em>DocumentStore</em> e o <em>DocumentSession, </em>vamos começar pelo  Store.</p>
<p>De uma forma simples, é com o <em>DocumentStore</em> que criamos a nossa comunicação com o RavenDB, por isso informamos no construtor da classe o endereço do servidor, mas devemos lembrar de chamar o método <em>Initialize</em> do <em>DocumentStore, </em>só instanciar a classe não é suficiente.</p>
<p><script src="https://gist.github.com/2590683.js"> </script></p>
<p>Com o <em>DocumentStore</em> criado, podemos criar o <em>DocumentSession</em> chamando o método <em>OpenSession</em>, é com o <em>DocumentSession</em> que conseguimos realizar operações no banco de dados, inclusões, consultas, alteraçoes ou seja o famoso CRUD, <em>create, read, update, delete</em>.</p>
<p><script src="https://gist.github.com/2590732.js"> </script></p>
<p>Por hoje é isso, informações mais detalhadas sobre <em>DocumentStore</em> e <em>DocumentSession</em> <a href="http://ravendb.net/docs/client-api" target="_blank">aqui</a>.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/05/ravendb-documentstore-e-documentsession/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/pjQVgV7Sw2g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/05/ravendb-documentstore-e-documentsession/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/05/ravendb-documentstore-e-documentsession/</feedburner:origLink></item>
		<item>
		<title>Começando com o RavenDB</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/2hocn60CWck/</link>
		<comments>http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 01:47:08 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[RavenDB]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[ravendb]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=936</guid>
		<description><![CDATA[Desde o artigo onde &#8220;brinquei&#8221; com o MongoDB, tomei conhecimento sobre o RavenDB, que é um NoSQL com vários recursos interessantes, open source e escrito em .NET. O projeto está no github e é liderado pelo Ayende Rahien, se você não conhece o cara, recomendo acompanhar o blog e ver outros produtos que ele faz ;)....<p><a href="http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Desde o artigo onde &#8220;brinquei&#8221; com o <a href="http://www.marcioalthmann.net/2011/01/brincando-com-o-mongodb/" target="_blank">MongoDB</a>, tomei conhecimento sobre o <a href="http://ravendb.net/" target="_blank">RavenDB</a>, que é um NoSQL com vários recursos interessantes, <a href="https://github.com/ravendb/ravendb" target="_blank">open source</a> e escrito em .NET.</p>
<p>O projeto está no <a href="https://github.com/ravendb/ravendb" target="_blank">github</a> e é liderado pelo <a href="http://ayende.com/Blog/" target="_blank">Ayende Rahien</a>, se você não conhece o cara, recomendo acompanhar o blog e ver outros produtos que ele faz ;).</p>
<p>Apesar do site do RavenDB não ser um exemplo em documentação, vou listar algumas funcionalidades do RavenDB:</p>
<ul>
<li>Schema free</li>
<li>Scalable (sharding, multi-tynancy, replication)</li>
<li>Transactional</li>
<li>Multi-level caching</li>
<li>Full-text search (built on top of Lucene)</li>
<li>High performance (aqui depois vou fazer um teste de desempenho entre o RavenDB, MongoDB e o SQL Server só para colocar um banco relacional na jogada)</li>
</ul>
<p>Existem outros detalhes interessantes, por exemplo, a possibilidade de rodar &#8220;embeded&#8221;, não precisando instanciar um servidor, e também tem o Rave Studio que permite visualizar e gerenciar seus documentos.</p>
<p>Pretendo nos outros artigos detalhar cada uma dessas opções do RavenDB, mas para não terminar o primeiro artigo sem código, após o download feito, é só executar o <em>Raven.Server.exe</em> que fica na pasta <em>Server, </em>com isso já temos o servidor rodando e podemos acessar o Raven Studio pela url <em>http://localhost:8080.</em></p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/04/ravenstudio.jpg" rel="lightbox[936]" title="ravenstudio"><img class="aligncenter size-medium wp-image-937" title="ravenstudio" src="http://www.marcioalthmann.net/wp-content/uploads/2012/04/ravenstudio-300x145.jpg" alt="" width="300" height="145" /></a></p>
<p>E o código do teste que inseriu esses albuns.</p>
<p><script src="https://gist.github.com/2554759.js?file=gistfile1.cs"></script></p>
<p>Por hoje é só, depois detalhes da implementação e mais informações sobre o RabenDB.</p>
<p>Abraços</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/2hocn60CWck" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/04/comecando-com-o-ravendb/</feedburner:origLink></item>
		<item>
		<title>Protobuf-net e objetos complexos</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/gK0kYp-Wy0U/</link>
		<comments>http://www.marcioalthmann.net/2012/03/protobuf-net-e-objetos-complexos/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 03:32:51 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Desempenho]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[desempenho]]></category>
		<category><![CDATA[deserialização]]></category>
		<category><![CDATA[protobuf-net]]></category>
		<category><![CDATA[serialização]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=924</guid>
		<description><![CDATA[Depois do último artigo onde mostrei o quanto o Protobuf-net é poderoso, algumas suspeitas apareceram sobre um problema do mesmo com objetos complexos, então resolvi refazer o teste deixando mais &#8220;complexo&#8221; o objeto serializado. Sem mais vamos aos objetos que serão serializados. [Serializable] [DataContract] public class Album { [DataMember] public string Titulo { get; set;...<p><a href="http://www.marcioalthmann.net/2012/03/protobuf-net-e-objetos-complexos/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Depois do <a href="http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/" target="_blank">último artigo</a> onde mostrei o quanto o Protobuf-net é poderoso, algumas suspeitas apareceram sobre um problema do mesmo com objetos complexos, então resolvi refazer o teste deixando mais &#8220;complexo&#8221; o objeto serializado. Sem mais vamos aos objetos que serão serializados.</p>
<pre class="brush: csharp">[Serializable]
[DataContract]
public class Album
{
    [DataMember]
    public string Titulo { get; set; }

    [DataMember]
    public int AnoDeLancamento { get; set; }

    [DataMember]
    public List&lt;Musica&gt; Musicas { get; set; }

    [DataMember]
    public Banda Banda { get; set; }

    public Album()
    {
        Banda = new Banda() {Nome = Environment.TickCount.ToString()};
        Musicas = new List();
        for (int i = 0; i &lt; 10; i++)
        {
            Musicas.Add(new Musica {Duracao = new TimeSpan(0, i, 0), Nome = i.ToString()});
        }
    }
}

[Serializable]
[DataContract]
public class Musica
{
    [DataMember]
    public string Nome { get; set; }

    [DataMember]
    public TimeSpan Duracao { get; set; }
}

[Serializable]
[DataContract]
public class Banda
{
    [DataMember]
    public string Nome { get; set; }

    [DataMember]
    public List Integrantes { get; set; }

    public Banda()
    {
        Integrantes = new List&lt;Integrante&gt;();
        for (int i = 0; i &lt; 5; i++)
        {
            Integrantes.Add(new Integrante {Nome = string.Format("Integrante {0}", i)});
        }
    }
}

[Serializable]
[DataContract]
public class Integrante
{
    [DataMember]
    public string Nome { get; set; }
}</pre>
<p>Ahhh Márcio mas esse objeto complexo não é tão complexo. Bom eu considero que está bom, caso alguém faça algum teste mais ousado por favor me envie!</p>
<p>Mesma execução explicada no artigo anterior, 100.000 serializações, 100.000 deserializações, e vamos aos resultados.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/03/chart-1.png" rel="lightbox[924]" title="chart (1)"><img class="aligncenter size-medium wp-image-926" title="chart (1)" src="http://www.marcioalthmann.net/wp-content/uploads/2012/03/chart-1-300x136.png" alt="" width="300" height="136" /></a></p>
<p>Além do gráfico, vou descrever os resultados, e novamente o Protobuf-net mostra que é disparado mais rápido que qualquer serializador disponível nativamente no .NET.</p>
<p><strong>Protobuf-net<br />
</strong>Serialização: 234 ms<br />
Deserialização: 1154 ms</p>
<p><strong>BinaryFormatter<br />
</strong>Serialização: 6833 ms<br />
Deserialização: 8019 ms</p>
<p><strong>DataContractSerializer<br />
</strong>Serialização: 1887 ms<br />
Deserialização: 4790 ms</p>
<p><strong>XmlSerializer<br />
</strong>Serialização: 3385 ms<br />
Deserialização: 7036 ms</p>
<p>Código fonte no <a href="https://github.com/marcioalthmann/Artigos/tree/master/Protobuf" target="_blank">github</a>.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/03/protobuf-net-e-objetos-complexos/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/gK0kYp-Wy0U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/03/protobuf-net-e-objetos-complexos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/03/protobuf-net-e-objetos-complexos/</feedburner:origLink></item>
		<item>
		<title>Google Protocol Buffers – Voando baixo com serializações utilizando o Protobuf-net</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/BXjRkfXuBpQ/</link>
		<comments>http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 19:23:28 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Desempenho]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[deserialização]]></category>
		<category><![CDATA[google protocol buffers]]></category>
		<category><![CDATA[protobuf-net]]></category>
		<category><![CDATA[serialização]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=903</guid>
		<description><![CDATA[Sempre estamos serializando ou deserializando algum objeto, manualmente ou deixando o framework fazer o trabalho &#8220;sujo&#8221;, não podemos esquecer que isso tem um custo, dependendo do tipo de serialização que escolhemos esse custo pode ser muito alto. E para nossa alegria o Google sabe isso, e ele criou o Google Protocol Buffers, é simples e...<p><a href="http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Sempre estamos serializando ou deserializando algum objeto, manualmente ou deixando o framework fazer o trabalho &#8220;sujo&#8221;, não podemos esquecer que isso tem um custo, dependendo do tipo de serialização que escolhemos esse custo pode ser muito alto.</p>
<p>E para nossa alegria o Google sabe isso, e ele criou o <a href="http://code.google.com/apis/protocolbuffers/docs/overview.html" target="_blank">Google Protocol Buffers</a>, é simples e rápido, na verdade muito rápido!!! Recomendo a leitura da documentação para entender o funcionamento do Protocol Buffers.</p>
<p>Uma descrição rápida do Protocol Buffers.</p>
<blockquote><p><strong>protocol buffers</strong> is the name of the binary serialization format used by Google for much of their data communications. It is designed to be:</p>
<p><strong>small in size &#8211; efficient data storage (far smaller than xml) </strong>cheap to process &#8211; both at the client and server <strong>platform independent &#8211; portable between different programming architectures </strong>extensible &#8211; to add new data to old messages</p></blockquote>
<p>Já que o Google mostrou pra todo mundo como fazer, uma implementação do Protocol Buffers foi criada em .net, chamada <a href="http://code.google.com/p/protobuf-net/" target="_blank">Protobuf-net</a>, ela funciona com praticamente todas as versões do .NET, suporta Silverlight, Mono e está no Google Code, então quem quiser pode ajudar no projeto! ;)</p>
<p>Serializar e deserializar objetos com o Protobuf-net é simples, então não vou ficar mostrando exemplos, mas vou colocar um teste de desempenho que fiz para comparar alguns tipos de serializações nativas do .NET contra o Protobuf-net.</p>
<p>A idéia do teste é simples, vou adicionar em uma lista de Albuns 100.000 albuns, a primeira parte que consistem em serializar vou percorrer essa lista e criar uma nova lista de byte[] com cada album serializado, e a parte da deserialização percorro a lista com byte[] da serialização e crio uma nova lista com Albuns.</p>
<p>A classe Album é simples, e está marcada com nossos conhecidos atributos de serialização e de contratos.</p>
<pre class="brush: csharp">[Serializable]
[DataContract]
public class Album
{
    [DataMember]
    public string Titulo { get; set; }
    [DataMember]
    public int AnoDeLancamento { get; set; }
}</pre>
<p>E agora o código que cria a lista com os albuns que serão serializados.</p>
<pre class="brush: csharp">private const int TotalDeAlbuns = 100000;
private static readonly List Albuns = Enumerable.Range(0, TotalDeAlbuns).Select(x =&gt; CriarAlbum(x)).ToList(); 

private static Album CriarAlbum(int numeroDoAlbum)
{
    return new Album {AnoDeLancamento = numeroDoAlbum, Titulo = numeroDoAlbum.ToString()};
}</pre>
<p>Eu fiz os testes utilizando as seguintes formatos de serialização:</p>
<ul class="list-blue">
<ul>
<li>Protobuf-net</li>
<li>BinaryFormatter</li>
<li>DataContractSerializer</li>
<li>XmlSerializer</li>
</ul>
</ul>
<p>E agora finalmente os códigos, são iguais só alterando o formato da serialização.</p>
<div class="tabs_container"><ul class="tabs"><li><a href="#">protobuf-net</a></li><li><a href="#">binaryformatter</a></li><li><a href="#">datacontractserializer</a></li><li><a href="#">xmlserializer</a></li></ul><div class="panes"><div class="pane"></p>
<pre class="brush: csharp">private static void TestesComProtobufNet()
{
    var albunsSerializados = new List();
    var albunsDesserializados = new List();

    Contador.Iniciar();

    foreach (var album in Albuns)
    {
        using (var memoryStream = new MemoryStream())
        {
            Serializer.Serialize(memoryStream, album);
            albunsSerializados.Add(memoryStream.ToArray());
        }
    }

    Contador.Parar();

    Console.WriteLine("Serializando {0} objetos com Protobuf-net: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);

    Contador.Iniciar();

    foreach (var album in albunsSerializados)
    {
        using (var memoryStream = new MemoryStream(album))
        {
            albunsDesserializados.Add(Serializer.Deserialize(memoryStream));
        }
    }

    Contador.Parar();

    Console.WriteLine("Deserializando {0} objetos com Protobuf-net: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);
    Console.WriteLine();
}</pre>
<p></div><div class="pane"></p>
<pre class="brush: csharp">private static void TestesComProtobufBinaryFormatter()
{
    var albunsSerializados = new List();
    var albunsDesserializados = new List();

    var binaryFormatter = new BinaryFormatter();

    Contador.Iniciar();

    foreach (var album in Albuns)
    {
        using (var memoryStream = new MemoryStream())
        {
            binaryFormatter.Serialize(memoryStream, album);
            albunsSerializados.Add(memoryStream.ToArray());
        }
    }

    Contador.Parar();

    Console.WriteLine("Serializando {0} objetos com BinaryFormatter: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);

    Contador.Iniciar();

    foreach (var album in albunsSerializados)
    {
        using (var memoryStream = new MemoryStream(album))
        {
            albunsDesserializados.Add((Album)binaryFormatter.Deserialize(memoryStream));
        }
    }

    Contador.Parar();

    Console.WriteLine("Deserializando {0} objetos com BinaryFormatter: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);
    Console.WriteLine();
}</pre>
<p></div><div class="pane"></p>
<pre class="brush: csharp">private static void TestesComDataContractSerializer()
{
    var albunsSerializados = new List();
    var albunsDesserializados = new List();

    var dataContractSerializer = new DataContractSerializer(typeof (Album));

    Contador.Iniciar();

    foreach (var album in Albuns)
    {
        using (var memoryStream = new MemoryStream())
        {
            dataContractSerializer.WriteObject(memoryStream, album);
            albunsSerializados.Add(memoryStream.ToArray());
        }
    }

    Contador.Parar();

    Console.WriteLine("Serializando {0} objetos com DataContractSerializer: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);

    Contador.Iniciar();

    foreach (var album in albunsSerializados)
    {
        using (var memoryStream = new MemoryStream(album))
        {
            albunsDesserializados.Add((Album) dataContractSerializer.ReadObject(memoryStream));
        }
    }

    Contador.Parar();

    Console.WriteLine("Deserializando {0} objetos com DataContractSerializer: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);
    Console.WriteLine();
}</pre>
<p></div><div class="pane"></p>
<pre class="brush: csharp">private static void TestesComXmlSerializer()
{
    var albunsSerializados = new List();
    var albunsDesserializados = new List();

    var xmlSerializer = new XmlSerializer(typeof (Album));

    Contador.Iniciar();

    foreach (var album in Albuns)
    {
        using (var memoryStream = new MemoryStream())
        {
            xmlSerializer.Serialize(memoryStream, album);
            albunsSerializados.Add(memoryStream.ToArray());
        }
    }

    Contador.Parar();

    Console.WriteLine("Serializando {0} objetos com XmlSerializer: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);

    Contador.Iniciar();

    foreach (var album in albunsSerializados)
    {
        using (var memoryStream = new MemoryStream(album))
        {
            albunsDesserializados.Add((Album)xmlSerializer.Deserialize(memoryStream));
        }
    }

    Contador.Parar();

    Console.WriteLine("Deserializando {0} objetos com XmlSerializer: {1} ms", TotalDeAlbuns, Contador.TempoTotalEmMilisegundos);
    Console.WriteLine();
}</pre>
<p></div></div></div>
<p>Execute a aplicação 3 vezes, em Release, segue o gráfico com a média de tempo de cada formato de serialização. E o Protobuf-net realmente da um show.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/03/chart.png" rel="lightbox[903]" title="chart"><img class="aligncenter size-medium wp-image-917" title="chart" src="http://www.marcioalthmann.net/wp-content/uploads/2012/03/chart-300x159.png" alt="" width="300" height="159" /></a></p>
<p>É interessante analisar esses tempos, o XmlSerializer é muito lento, e o DataContractSerializer manda bem para serializar, mas para deserializar não é tão bom.</p>
<p>É importante ver que mesmo com o .NET disponibilizando vários formatos de serialização, precisamos sair da &#8220;zona de conforto&#8221; e buscar melhores alternativas, é claro que isso depende do cenário de cada um, mas caso esteja atendendo cenários críticos onde qualquer segundo faz diferença é sempre bom abrir a cabeça e aceitar novidades ;).</p>
<p>O código fonte do projeto está no <a href="https://github.com/marcioalthmann/Artigos/tree/master/Protobuf" target="_blank">github</a>.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/BXjRkfXuBpQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/03/google-protocol-buffers-voando-baixo-com-serializacoes-utilizando-o-protobuf-net/</feedburner:origLink></item>
		<item>
		<title>Descobrindo se o SO ou Processo em execução é 64 bits</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/EqaK13Od8-Y/</link>
		<comments>http://www.marcioalthmann.net/2012/01/descobrindo-se-o-so-ou-processo-em-execucao-e-64-bits/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 15:12:48 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[64bits]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=889</guid>
		<description><![CDATA[E ai pessoal, beleza? Mais uma dica simples, utilizando um recurso adicionado no .NET 4.0, para saber se o Sistema Operacional é 64 bits, ou o processo que está executando nossa lógica é 64 bits temos jeitos simples para fazer isso. Para descobrir se o sistema operacional é 64 bits é só fazer: Environment.Is64BitOperatingSystem E...<p><a href="http://www.marcioalthmann.net/2012/01/descobrindo-se-o-so-ou-processo-em-execucao-e-64-bits/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>E ai pessoal, beleza?</p>
<p>Mais uma dica simples, utilizando um recurso adicionado no .NET 4.0, para saber se o Sistema Operacional é 64 bits, ou o processo que está executando nossa lógica é 64 bits temos jeitos simples para fazer isso.</p>
<p>Para descobrir se o sistema operacional é 64 bits é só fazer:</p>
<pre class="brush: csharp">
Environment.Is64BitOperatingSystem
</pre>
<p>E para saber se o processo é 64 bits:</p>
<pre class="brush: csharp">
Environment.Is64BitProcess
</pre>
<p>Ambas as propriedades retornam um booleano.</p>
<p>Por enquanto é isso.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/01/descobrindo-se-o-so-ou-processo-em-execucao-e-64-bits/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/EqaK13Od8-Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/01/descobrindo-se-o-so-ou-processo-em-execucao-e-64-bits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/01/descobrindo-se-o-so-ou-processo-em-execucao-e-64-bits/</feedburner:origLink></item>
		<item>
		<title>Utilizando o atributo ObsoleteAttribute</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/MgnQedozOpM/</link>
		<comments>http://www.marcioalthmann.net/2012/01/utilizando-o-atributo-obsoleteattribute/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 00:37:27 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[obsolete]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=881</guid>
		<description><![CDATA[As vezes quando utilizamos alguns objetos ou métodos do .Net, o Intellisense mostra o método riscado, e nos avisa que o mesmo está obsoleto, e devemos utilizar outra classe ou método no lugar, e podemos utilizar esse recurso nos nossos códigos! Trabalho criando ferramentas e frameworks pra outros desenvolvedores, e nem sempre quando disponibilizamos alguma...<p><a href="http://www.marcioalthmann.net/2012/01/utilizando-o-atributo-obsoleteattribute/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>As vezes quando utilizamos alguns objetos ou métodos do .Net, o Intellisense mostra o método riscado, e nos avisa que o mesmo está obsoleto, e devemos utilizar outra classe ou método no lugar, e podemos utilizar esse recurso nos nossos códigos!</p>
<p>Trabalho criando ferramentas e frameworks pra outros desenvolvedores, e nem sempre quando disponibilizamos alguma API para utilização, podemos sair removendo métodos por exemplo, não sabemos quem utilizou, e se em alguma possível atualização o software vai parar de funcionar ou não, e o atributo Obsolete pode nos ajudar nesse cenário, informando o que está obsoleto na API e será descartado em breve, ou simplesmente recomendando uma alternativa melhor!</p>
<p>A utilização do atributo é simples, vou pegar o código do <a href="https://github.com/marcioalthmann/BasicIoC" target="_blank">BasicIoC </a>e criar um método obsoleto de propósito, só preciso informar a mensagem que será mostrada para quem for utilizar o método.</p>
<pre class="brush: csharp">
[Obsolete(&quot;This method is obsolete; use method Register instead.&quot;)]
public Container Map&lt;T&gt;()
{
    _baseType = typeof (T);
    return this;
}
</pre>
<p>E o interessante é que o Intellisense já ajuda o desenvolvedor mostrando que o método é obsoleto.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete01.jpg" rel="lightbox[881]" title="obsolete01"><img class="aligncenter size-medium wp-image-882" title="obsolete01" src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete01-300x92.jpg" alt="" width="300" height="92" /></a></p>
<p>Isso não impede a utilização do método, mas mostra avisos quando compilamos que utilizamos um método obsoleto.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete02.jpg" rel="lightbox[881]" title="obsolete02"><img class="aligncenter size-medium wp-image-883" title="obsolete02" src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete02-300x51.jpg" alt="" width="300" height="51" /></a></p>
<p>Mas podemos adicionar um segundo parâmetra booleano quando configuramos o atributo, forçando um erro de compilação caso existe algum código utilizando um método ou classe obsoleta.</p>
<pre class="brush: csharp">
[Obsolete(&quot;This method is obsolete; use method Register instead.&quot;, true)]
public Container Map&lt;T&gt;()
{
    _baseType = typeof (T);
    return this;
}
</pre>
<p>Agora o código não compila mais, no lugar de um aviso um erro de compilação é mostrado, mostrando que estamos utilizando um método obsoleto.</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete03.jpg" rel="lightbox[881]" title="obsolete03"><img class="aligncenter size-medium wp-image-884" title="obsolete03" src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/obsolete03-300x50.jpg" alt="" width="300" height="50" /></a></p>
<p>Por hoje é isso.</p>
<p>Até o próximo post.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/01/utilizando-o-atributo-obsoleteattribute/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/MgnQedozOpM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/01/utilizando-o-atributo-obsoleteattribute/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/01/utilizando-o-atributo-obsoleteattribute/</feedburner:origLink></item>
		<item>
		<title>Loops inspirados em Ruby no C#</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/gF8OlfzYklI/</link>
		<comments>http://www.marcioalthmann.net/2012/01/loops-inspirados-em-ruby-no-c/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 03:24:40 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[extension methods]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=876</guid>
		<description><![CDATA[Existem algumas formas interessantes de fazer loops em Ruby, que são times, upto e downto, que estão disponiveis em algum número, veja documentação completa. A idéia é simples, .times vai executar o códido o número de vezes informado, upto vai executar o código o número de vezes incrementando do valor inicial até o final, e...<p><a href="http://www.marcioalthmann.net/2012/01/loops-inspirados-em-ruby-no-c/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Existem algumas formas interessantes de fazer loops em Ruby, que são <em>times, upto </em>e <em>downto, </em>que estão disponiveis em algum número, <a href="http://en.wikibooks.org/wiki/Ruby_Programming/Reference/Objects/Numeric/Integer" target="_blank">veja documentação completa</a>.</p>
<p>A idéia é simples, <em>.times</em> vai executar o códido o número de vezes informado, <em>upto</em> vai executar o código o número de vezes incrementando do valor inicial até o final, e <em>downto</em> vai executar o código o número de vezes decrementando do valor inicial até o final.</p>
<p>Veja o código:</p>
<p>[sourcecode language="ruby"]<br />
puts &quot;testando times&quot;<br />
2.times {|i| print i, &quot; &quot;}<br />
puts<br />
puts &quot;testando upto&quot;<br />
1.upto(5) {|i| print i, &quot; &quot;}<br />
puts<br />
puts &quot;testando downto&quot;<br />
10.downto(5) {|i| print i, &quot; &quot;}<br />
[/sourcecode]</p>
<p>Resultado:</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/ruby1.jpg" rel="lightbox[876]" title="ruby1"><img class="aligncenter size-medium wp-image-877" title="ruby1" src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/ruby1-300x131.jpg" alt="" width="300" height="131" /></a></p>
<p>Simples e interessante, no C# não temos nada disso, mas podemos criar algo parecido utilizando um pouco de <a href="http://www.marcioalthmann.net/2009/09/metodos-de-extensao/" target="_blank">Métodos de Extensão</a>, não vou explicar nesse post o que são e como criar as extensões, vejam no post linkado.</p>
<p>Segue os códigos das Extensões e do aplicativo de teste:</p>
<p>[sourcecode language="csharp"]<br />
    public static class Extensions<br />
    {<br />
        public static void Times(this int value, Action&lt;int&gt; action)<br />
        {<br />
            for (int i = 0; i &lt; value; i++)<br />
            {<br />
                action(i);<br />
            }<br />
        }</p>
<p>        public static IEnumerable&lt;int&gt; UpTo(this int start, int end)<br />
        {<br />
            for (int i = start; i &lt;= end; i++)<br />
            {<br />
                yield return i;<br />
            }<br />
        }</p>
<p>        public static IEnumerable&lt;int&gt; DownTo(this int start, int end)<br />
        {<br />
            for (int i = start; i &gt;= end; i&#8211;)<br />
            {<br />
                yield return i;<br />
            }<br />
        }</p>
<p>        public static void Each&lt;T&gt;(this IEnumerable&lt;T&gt; enumerable, Action&lt;T&gt; action)<br />
        {<br />
            foreach (var value in enumerable)<br />
            {<br />
                action(value);<br />
            }<br />
        }<br />
    }</p>
<p>    class Program<br />
    {<br />
        static void Main(string[] args)<br />
        {<br />
            Console.WriteLine(&quot;testando times&quot;);<br />
            3.Times(x =&gt; Console.Write(&quot;{0} &quot;, x));<br />
            Console.WriteLine();<br />
            Console.WriteLine(&quot;testando upto&quot;);<br />
            5.UpTo(10).Each(x =&gt; Console.Write(&quot;{0} &quot;, x));<br />
            Console.WriteLine();<br />
            Console.WriteLine(&quot;testando downto&quot;);<br />
            10.DownTo(5).Each(x =&gt; Console.Write(&quot;{0} &quot;, x));</p>
<p>            Console.ReadLine();<br />
        }<br />
    }<br />
[/sourcecode]</p>
<p>E o resultado:</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/csharp1.jpg" rel="lightbox[876]" title="csharp1"><img class="aligncenter size-medium wp-image-878" title="csharp1" src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/csharp1-300x195.jpg" alt="" width="300" height="195" /></a></p>
<p>Bom é isso, o código é simples mas foi divertido e gostei do resultado final, apesar de achar que em Ruby fica muito melhor gostei do resultado final em C#, e para quem não conhece Ruby recomendo estudar, não precisa trabalhar com Ruby, mas é muito interessante conhecer novas tecnologias, mais sobre o que penso sobre isso <a href="http://www.marcioalthmann.net/2011/04/por-que-no-estudar-novas-tecnologias/" target="_blank">nesse post.</a>.</p>
<p>Por enquanto é só, código no <a href="https://github.com/marcioalthmann/Artigos/tree/master/Extensions" target="_blank">GitHub</a>.</p>
<p>Abraços.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/01/loops-inspirados-em-ruby-no-c/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/gF8OlfzYklI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/01/loops-inspirados-em-ruby-no-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/01/loops-inspirados-em-ruby-no-c/</feedburner:origLink></item>
		<item>
		<title>JQuery – Upload simples com o PlUpload</title>
		<link>http://feedproxy.google.com/~r/MarcioFabioAlthmann/~3/Xn3IlDdaI2A/</link>
		<comments>http://www.marcioalthmann.net/2012/01/jquery-upload-simples-com-o-plupload/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 00:16:59 +0000</pubDate>
		<dc:creator>Márcio Fábio Althmann</dc:creator>
				<category><![CDATA[Java Script]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.marcioalthmann.net/?p=870</guid>
		<description><![CDATA[Mais uma dica de um ótimo plugin para utilizarmos nos nossos projetos. Sempre precisamos fazer upload de arquivos, fotos, documentos e é interessante disponibilizar para o usuário uma interface rica, com suporte a drag and drop, progresso do upload, upload de multiplos arquivos entre outras opções, e nisso o PlUpload é um ótimo plugin, apesar...<p><a href="http://www.marcioalthmann.net/2012/01/jquery-upload-simples-com-o-plupload/"> Leia mais →</a>]]></description>
			<content:encoded><![CDATA[<p>Mais uma dica de um ótimo plugin para utilizarmos nos nossos projetos.</p>
<p>Sempre precisamos fazer upload de arquivos, fotos, documentos e é interessante disponibilizar para o usuário uma interface rica, com suporte a drag and drop, progresso do upload, upload de multiplos arquivos entre outras opções, e nisso o PlUpload é um ótimo plugin, apesar de não funcionar somente com JQuery, ele possui runtimes de Flash, Silverlight e alguns outros, mas hoje vou utilizar o <em>Jquery queue widget </em>para fazer uploads.</p>
<p>Para fazer download é só <a href="http://www.plupload.com/download.php" target="_blank">clicar aqui</a>, existe uma versão gratuita, ou se alguém quiser pode também licenciar o plugin de upload, o que muda é suporte e ajuda os caras a ganhar um merecido dinheiro :).</p>
<p>Existem várias opções de runtime, e diversos arquivos no arquivo de download, segue os arquivos que utilizei no exemplo.</p>
<p>[sourcecode language="html"]<br />
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/plupload.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<br />
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/plupload.html4.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<br />
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/plupload.html5.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<br />
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/jquery.plupload.queue.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<br />
&lt;link href=&quot;@Url.Content(&quot;~/Content/plupload/jquery.plupload.queue.css&quot;)&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;<br />
[/sourcecode]</p>
<p>Um detalhe é que para funcionar corretamente, também adicione as imagens disponibilizadas no arquivo de download, e preste atenção no arquivo de .css para ver o diretório de colocar as imagens, ou altere o <em>jquery.upload.queue.css<em> para apontar para sua pasta de imagens.</em></em></p>
<p>Feito isso eu criei um método <em>upload</em> no meu controller <em>plupload</em>, segue o código que não é foco do artigo fazer o armazenamento dos arquivos :), e também repare no parâmetro do método que tem que ser <em>HttpPostedFileBase</em>.</p>
<p>[sourcecode language="csharp"]<br />
[HttpPost]<br />
public void Upload(HttpPostedFileBase file)<br />
{<br />
    // Lógica para salvar a foto<br />
}<br />
[/sourcecode]</p>
<p>Feito isso precisamos configurar nosso HTML, que só vai ter uma div com um id específico, bem difícil assim mesmo :), é nessa div que o plugin de upload será montado.</p>
<p>[sourcecode language="html"]<br />
&lt;div id=&quot;upload&quot;&gt;&lt;/div&gt;<br />
[/sourcecode]</p>
<p>E para finalizar, temos o JQuery que configura o plugin na div que criamos, detalhe para algumas configurações básicas do plugin, onde informo os runtimes que vamos utilizar, tamanho máximo de cada arquivo, a URL que ele vai enviar as fotos, e as extensões suportadas. Mais configurações podem ser encontradas na documentação do plugin.</p>
<p>[sourcecode language="javascript"]<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
    $(function () {</p>
<p>        $(&quot;#upload&quot;).pluploadQueue({<br />
           runtimes : &quot;html5,html4&quot;,<br />
           url : &quot;/plupload/upload&quot;,<br />
           max_file_size : &quot;4mb&quot;,<br />
           filters: [<br />
                {title : &quot;Imagens&quot;, extensions : &quot;jpg,png&quot;}<br />
           ]<br />
        });</p>
<p>    });<br />
&lt;/script&gt;<br />
[/sourcecode]</p>
<p>Feito isso é só testar e ver o upload funcionando, com progresso, opção para exclusão de itens antes de iniciar o upload, muito bom!</p>
<p><a href="http://www.marcioalthmann.net/wp-content/uploads/2012/01/plupload.jpg" rel="lightbox[870]" title="plupload"><img src="http://www.marcioalthmann.net/wp-content/uploads/2012/01/plupload-300x168.jpg" alt="" title="plupload" width="300" height="168" class="aligncenter size-medium wp-image-871" /></a></p>
<p>Código fonte no <a href="https://github.com/marcioalthmann/Artigos/tree/master/JQuery/JQuery" target="_blank">GitHub</a>.</p>
<p>Abraços e até o próximo post.</p>
<div id="fb-like" style=""><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.marcioalthmann.net/2012/01/jquery-upload-simples-com-o-plupload/&amp;layout=button_count&amp;show_faces=false&amp;width=300&amp;action=like&amp;font=&amp;colorscheme=light&amp;locale=en_US" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:20px"></iframe></div><img src="http://feeds.feedburner.com/~r/MarcioFabioAlthmann/~4/Xn3IlDdaI2A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.marcioalthmann.net/2012/01/jquery-upload-simples-com-o-plupload/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.marcioalthmann.net/2012/01/jquery-upload-simples-com-o-plupload/</feedburner:origLink></item>
	</channel>
</rss><!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->

