<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Lluís Franco on Geeks.ms</title><link>http://geeks.ms/blogs/lfranco/default.aspx</link><description>El Framework y yo...</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Alucina: Premiado C# MVP of the year!</title><link>http://geeks.ms/blogs/lfranco/archive/2012/02/15/alucina-premiado-c-mvp-of-the-year.aspx</link><pubDate>Wed, 15 Feb 2012 09:06:08 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203364</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>22</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=203364</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2012/02/15/alucina-premiado-c-mvp-of-the-year.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/mvplogohor_5F00_4444AE95.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="mvplogohor" border="0" alt="mvplogohor" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/mvplogohor_5F00_thumb_5F00_681D6022.png" width="227" height="94" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sorprendido. Perplejo. Flipado. Esas son ahora mismo las palabras que mejor pueden definir mi estado actual.&lt;/p&gt;  &lt;p align="justify"&gt;No obstante, a medida que voy escribiendo estas líneas y lo voy realizando voy experimentando una alegría enorme, que ya está se empezando a transformar en una sonrisa beatífica, por no decir estúpida. Y es que he recibido un mail de &lt;a href="http://twitter.com/#!/lisafeig"&gt;Lisa Feigenbaum&lt;/a&gt; (Microsoft Community Program Manager) con un mensaje que dice: &lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;&lt;em&gt;“Congratulations on being awarded C# MVP of the Year based on your contributions in 2011!”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p align="justify"&gt;WOW! Mola mucho, aunque la verdad y aunque suene a tópico no me lo esperaba ni de coña...&lt;/p&gt;  &lt;p align="justify"&gt;Durante los últimos 9 años he tenido la suerte de ser reconocido como &lt;a href="http://mvp.support.microsoft.com/"&gt;Microsoft MVP&lt;/a&gt; y eso es algo que valoro mucho. No tanto por ser reconocido como ‘experto’ (cuesta mucho emplear esa palabra habiendo gente tan condenadamente buena), sino por el hecho que se reconozca la labor de ayudar a la comunidad. Que al fin y al cabo es lo que debería contar en el programa MVP, y -seamos sinceros- no siempre es lo único que cuenta.&lt;/p&gt;  &lt;p align="justify"&gt;Pues bien, ahora resulta que en una votación entre los 234 compañeros MVP de la categoría de C# repartidos por todo el mundo y el equipo de producto han decidido nombrarme MVP de C# del año, sea lo que sea eso, que la verdad, todavía no lo tengo muy claro.&lt;/p&gt;  &lt;p align="justify"&gt;De entrada el próximo 2 de Marzo, hay una cena en Seattle con S. Somasegar (“Soma”), Senior Vice President de la división de desarrollo en Microsoft, así como otros peces gordos y miembros destacados de la comunidad. Para mi desgracia, no voy a poder asistir pues vuelvo de Seattle en mismo día por la mañana pero durante mi estancia en el campus de Microsoft trataré de al menos tomarme una cerveza con alguno de estos personajes :-)&lt;/p&gt;  &lt;p align="justify"&gt;Desde aquí quiero dar la enhorabuena al resto de premiados (he contado 29 en todas las categorías) y a todos mis compañeros. De verdad gente, sois grandes! :-D&lt;/p&gt;  &lt;p align="justify"&gt;Un abrazo a todos,&lt;/p&gt;  &lt;p align="justify"&gt;PD – La semana que viene ya os empezaré a contar mis batallitas en Seattle, en directo.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203364" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/MVP/default.aspx">MVP</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Award/default.aspx">Award</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2012/default.aspx">2012</category></item><item><title>Parallel Series: La clase estática Parallel</title><link>http://geeks.ms/blogs/lfranco/archive/2012/02/14/parallel-series-la-clase-est-225-tica-parallel.aspx</link><pubDate>Tue, 14 Feb 2012 10:32:46 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203344</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=203344</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2012/02/14/parallel-series-la-clase-est-225-tica-parallel.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/parallel_5F00_class_5F00_0428053C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="parallel_class" border="0" alt="parallel_class" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/parallel_5F00_class_5F00_thumb_5F00_42411FED.png" width="504" height="346" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Acabo de publicar otro post relacionado con las ‘Parallel Series’:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3 métodos para los reyes elfos bajo el cielo&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Hoy quiero hablaros de la &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.aspx"&gt;clase estática Parallel&lt;/a&gt;. Esta clase provee soporte para paralelizar bucles y regiones, y al igual que PLINQ su uso es muy sencillo. Cabe destacar que está especialmente optimizada para iteraciones, y que en este contexto se desenvuelve un poco mejor que PLINQ. No hay una diferencia significativa en tiempos absolutos, pero puede verse perfectamente si utilizamos el magnífico profiler de Visual Studio 2010. No obstante, pueden existir situaciones en las que si se necesita afinar mucho el rendimiento en iteraciones, y aquí es dónde tiene más sentido utilizar dos de los tres métodos de esta clase: &lt;strong&gt;For&lt;/strong&gt; y &lt;strong&gt;ForEach&lt;/strong&gt;. Al tercero lo llamaremos &lt;a href="http://es.wikipedia.org/wiki/C%C3%ADrdan"&gt;Cirdan&lt;/a&gt; y apenas aparecerá en esta historia (en realidad me refiero a Invoke pero tampoco aparecerá por aquí)...&lt;/p&gt;  &lt;p&gt;Podéis acceder al artículo completo aquí:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://lluisfranco.com/2011/06/26/parallel-series-la-clase-esttica-parallel/" href="http://lluisfranco.com/2011/06/26/parallel-series-la-clase-esttica-parallel/"&gt;http://lluisfranco.com/2011/06/26/parallel-series-la-clase-esttica-parallel/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Un saludo,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203344" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Serie/default.aspx">Serie</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Codigo/default.aspx">Codigo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Microsoft/default.aspx">Microsoft</category></item><item><title>Parallel Series: Video – 02 PLINQ</title><link>http://geeks.ms/blogs/lfranco/archive/2012/02/13/parallel-series-video-02-plinq.aspx</link><pubDate>Mon, 13 Feb 2012 08:44:29 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203327</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=203327</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2012/02/13/parallel-series-video-02-plinq.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/claqueta_5F00_5C889192.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="claqueta" border="0" alt="claqueta" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/claqueta_5F00_thumb_5F00_7A1A6C91.jpg" width="244" height="242" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Acabo de publicar otro vídeo de las las ‘Parallel Series’. Os dejo aquí también el enlace:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://lluisfranco.wordpress.com/2011/07/01/parallel-series-video-02-plinq/" href="http://lluisfranco.wordpress.com/2011/07/01/parallel-series-video-02-plinq/"&gt;http://lluisfranco.wordpress.com/2011/07/01/parallel-series-video-02-plinq/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En este segundo vídeo de las Parallel Series haremos un breve recorrido por las principales características de Parallel LINQ.&lt;/p&gt;  &lt;p&gt;Un saludo,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203327" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Serie/default.aspx">Serie</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Codigo/default.aspx">Codigo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Microsoft/default.aspx">Microsoft</category></item><item><title>Luces, cámara… Action!</title><link>http://geeks.ms/blogs/lfranco/archive/2012/02/10/luces-c-225-mara-action.aspx</link><pubDate>Fri, 10 Feb 2012 16:30:11 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203288</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=203288</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2012/02/10/luces-c-225-mara-action.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/Action2_5F00_7B21430D.jpg"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="Action2" border="0" alt="Action2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/Action2_5F00_thumb_5F00_7898114F.jpg" width="204" height="204" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Acabo de publicar otro post relacionado con las ‘Parallel Series’. Os dejo aquí también el enlace:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://lluisfranco.com/2012/02/08/luces-camara-action/" href="http://lluisfranco.com/2012/02/08/luces-camara-action/"&gt;http://lluisfranco.com/2012/02/08/luces-camara-action/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Un saludo,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203288" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Serie/default.aspx">Serie</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Codigo/default.aspx">Codigo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Microsoft/default.aspx">Microsoft</category></item><item><title>Nacen las Parallel Series</title><link>http://geeks.ms/blogs/lfranco/archive/2012/02/08/nacen-las-parallel-series.aspx</link><pubDate>Wed, 08 Feb 2012 12:55:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203256</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=203256</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2012/02/08/nacen-las-parallel-series.aspx#comments</comments><description>&lt;p align="justify"&gt;Como ya os promet&amp;iacute; a algunos de vosotros, he empezado a publicar una nueva serie que promete ser la m&amp;aacute;s larga de las que he publicado hasta ahora. El tema a tratar va a ser la programaci&amp;oacute;n paralela mediante la &lt;a href="http://msdn.microsoft.com/en-us/library/dd460693.aspx"&gt;Task Parallel Library&lt;/a&gt; incorporada en .NET 4.0 y Visual Studio 2010.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/parallelism_5F00_0281FFE9.png"&gt;&lt;img height="172" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/parallelism_5F00_thumb_5F00_46098B3E.png" alt="parallelism" border="0" title="parallelism" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Cuento con la ventaja de haber estado creando material durante el &amp;uacute;ltimo a&amp;ntilde;o y medio, en el que he publicado algunos documentos, varios v&amp;iacute;deos y hasta un webcast con los chicos de SecondNug. Todo este material y alguno m&amp;aacute;s que tengo en mente formar&amp;aacute; parte de las &lt;a href="http://lluisfranco.com/2011/01/25/parallel-series-indice-de-contenidos/"&gt;Parallel Series&lt;/a&gt;, que ser&amp;aacute;n publicadas en mi &lt;a href="http://lluisfranco.com"&gt;otro blog&lt;/a&gt; y no aqu&amp;iacute;, porque la publicaci&amp;oacute;n cruzada entre WordPress y Community Server es un autentico drama.&lt;/p&gt;
&lt;p align="justify"&gt;Sin embargo, prometo avisar aqu&amp;iacute; cada vez que publique un nuevo post se la serie. De momento tengo unos cinco o seis art&amp;iacute;culos publicados (la serie posiblemente llegar&amp;aacute; a los 20) y mi intenci&amp;oacute;n es ir publicando al menos uno por semana, y si puedo dos mucho mejor :-)&lt;/p&gt;
&lt;p align="justify"&gt;Os dejo con el &amp;iacute;ndice de contenidos de la serie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;a href="http://lluisfranco.com/2011/01/25/parallel-series-indice-de-contenidos/"&gt;&amp;Iacute;ndice de contenidos&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Y algunos de los art&amp;iacute;culos ya publicados (y los que faltan):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;Iacute;ndice de contenidos de las Parellel Series&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/01/10/task-parallel-library-el-alfa/"&gt;El Alfa (Pr&amp;oacute;logo)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/02/21/parallel-series-un-poco-de-historia/"&gt;Un poco de historia&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/03/03/parallel-series-aclarando-conceptos-base/"&gt;Aclarando conceptos base&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/03/07/parallel-series-video-01-bases/"&gt;Video: 01 Bases&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/05/31/parallel-series-parallel-linq-plinq/"&gt;PLINQ: Parallel LINQ&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.wordpress.com/2011/07/01/parallel-series-video-02-plinq/"&gt;Video: 02 PLINQ&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2011/06/26/parallel-series-la-clase-esttica-parallel/"&gt;Parallel static class&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Video: 03 Parallel Class&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tasks, la 8&amp;ordf; maravilla&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Video: 04 Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Problemas de concurrencia&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Video: 05 Concurrent collections&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;El depurador: Tu fiel amigo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Video: Debugging &amp;amp; profiling&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Webcast con los chicos de SecondNug&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Materiales y presentaciones de mis eventos&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;C# futures: async &amp;amp; await&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Art&amp;iacute;culos relacionados&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2012/02/08/programacin-funcional-para-el-resto-de-nosotros/"&gt;Programaci&amp;oacute;n funcional para el resto de nosotros&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://lluisfranco.com/2012/02/08/luces-camara-action/"&gt;Luces, c&amp;aacute;mara&amp;hellip; Action!&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;A medida que vaya publicando en el otro blog ir&amp;eacute; actualizando tambi&amp;eacute;n este de aqu&amp;iacute;. &lt;/p&gt;
&lt;p align="justify"&gt;Un saludo!&lt;/p&gt;
&lt;p align="justify"&gt;PD &amp;ndash; Me encantar&amp;iacute;a recibir feedback vuestro, as&amp;iacute; que se agradecer&amp;aacute;n comentarios de todo tipo (en el otro blog).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203256" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Serie/default.aspx">Serie</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Codigo/default.aspx">Codigo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Microsoft/default.aspx">Microsoft</category></item><item><title>Abandona tus DataSets. Ellos no van a tener piedad de ti.</title><link>http://geeks.ms/blogs/lfranco/archive/2011/12/28/abandona-tus-datasets-ellos-no-van-a-tener-piedad-de-ti.aspx</link><pubDate>Wed, 28 Dec 2011 12:25:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202350</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=202350</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/12/28/abandona-tus-datasets-ellos-no-van-a-tener-piedad-de-ti.aspx#comments</comments><description>&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/add_5F00_dataset_5F00_51B1C8BF.jpg"&gt;&lt;img height="149" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/add_5F00_dataset_5F00_thumb_5F00_35C093C7.jpg" alt="add_dataset" border="0" title="add_dataset" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&amp;iquest;Todav&amp;iacute;a est&amp;aacute;s usando DataSets en tu aplicaci&amp;oacute;n .NET?&lt;/p&gt;
&lt;p align="justify"&gt;&amp;iquest;Eres consciente de que los DataSets son actualmente unas p&amp;eacute;simas herramientas para trabajar con datos?&lt;/p&gt;
&lt;p align="justify"&gt;&amp;iquest;No utilizas tecnolog&amp;iacute;as m&amp;aacute;s modernas porque te falta capacitaci&amp;oacute;n para ello?&lt;/p&gt;
&lt;p align="justify"&gt;Entonces est&amp;aacute;s de enhorabuena! :-D&lt;/p&gt;
&lt;p align="justify"&gt;Hartos como estamos del uso de los infames DataSets, &lt;a href="http://twitter.com/_PedroHurtado"&gt;Pedro Hurtado&lt;/a&gt;, &lt;a href="http://twitter.com/lluisfranco"&gt;un servidor&lt;/a&gt; y otros compa&amp;ntilde;eros, con la colaboraci&amp;oacute;n de Microsoft, hemos decidido crear un concurso en el que los ganadores podr&amp;aacute;n acceder a capacitaci&amp;oacute;n gratuita, para de este modo poder utilizar las tecnolog&amp;iacute;as m&amp;aacute;s modernas en sus aplicaciones: LINQ to SQL, Entity Framework 4.0, NHibernate o incluso RDO.Resultsets.&lt;/p&gt;
&lt;p align="justify"&gt;Para acceder al concurso basta con participar en esta encuesta (son s&amp;oacute;lo unas pocas preguntas):&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://apps.facebook.com/mis-encuestas/535kd442" title="http://apps.facebook.com/mis-encuestas/535kd442"&gt;http://apps.facebook.com/mis-encuestas/535kd442&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;S&amp;oacute;lo necesitas un par de minutos y podr&amp;aacute;s acceder al sorteo.&lt;/p&gt;
&lt;p align="justify"&gt;An&amp;iacute;mate y no tengas piedad de los DataSets&amp;hellip; Ellos no la van a tener contigo :-)&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;*** Edici&amp;oacute;n: &amp;lt;comunicado de los organizadores de la broma&amp;gt; ***&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Hola de nuevo,&lt;/p&gt;
&lt;p align="justify"&gt;Bueno transcurrido el tiempo de finalizaci&amp;oacute;n del concurso de &amp;quot;Matemos al DataSet&amp;quot;. El ganador para optar a la capacitaci&amp;oacute;n es &lt;strong&gt;Leandro Tuttini&lt;/strong&gt; (aunque realmente no la necesite), puesto que nadie m&amp;aacute;s que el se dio cuenta de que se trataba de una bonita inocentada. &amp;iquest;O es que los dataset os tienen tan inmersos en exception que nadie sab&amp;iacute;a que ayer en Espa&amp;ntilde;a era 28 de Diciembre de 2011, dia de los Santos Inocentes?&lt;/p&gt;
&lt;p align="justify"&gt;La broma estaba oculta en este parrafo:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;em&gt;&amp;quot;...para de este modo poder utilizar las tecnolog&amp;iacute;as m&amp;aacute;s modernas en sus aplicaciones: LINQ to SQL, Entity Framework 4.0, NHibernate o incluso RDO.Resultsets.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Y como bien mencion&amp;oacute; Leandro, los ResultSets de RDO son antiguos artefactos de Visual Basic, anteriores incluso a los RecordSets de ADO.&lt;/p&gt;
&lt;p align="justify"&gt;En fin, feliz d&amp;iacute;a de los santos inocentes++;&lt;/p&gt;
&lt;p align="justify"&gt;Nota personal: Viendo el debate y la atenci&amp;oacute;n que se ha creado, creo que podr&amp;iacute;a ser interesante plantearnos ayudar a todos aquellos que deseen conocer estos artefactos del diablo que son los DataSets (eso desgraciadamente, no es ninguna inocentada).&lt;/p&gt;
&lt;p align="justify"&gt;Como lo veis? :-D&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202350" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Tecnologia/default.aspx">Tecnologia</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/DataSets/default.aspx">DataSets</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Encuesta/default.aspx">Encuesta</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2011/default.aspx">2011</category></item><item><title>Xbox 720 integrará Kinect con Windows Phone de forma nativa</title><link>http://geeks.ms/blogs/lfranco/archive/2011/12/28/xbox-720-integrar-225-kinect-con-windows-phone-de-forma-nativa.aspx</link><pubDate>Wed, 28 Dec 2011 08:12:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202344</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=202344</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/12/28/xbox-720-integrar-225-kinect-con-windows-phone-de-forma-nativa.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/Xbox_5F00_720_5F00_2C73B298.png"&gt;&lt;img height="213" width="350" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/Xbox_5F00_720_5F00_thumb_5F00_29EA80DA.png" alt="Xbox_720" border="0" title="Xbox_720" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Hola a todos,&lt;/p&gt;
&lt;p align="justify"&gt;Se est&amp;aacute; hablando mucho de la pr&amp;oacute;xima consola Xbox, la llamada 720 que supuestamente &lt;a href="http://www.videogamesblogger.com/2007/03/13/next-xbox-720-to-launch-in-2011-2012-according-to-microsoft.htm"&gt;aparecer&amp;aacute; en verano del a&amp;ntilde;o que viene&lt;/a&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;Una de las caracter&amp;iacute;sticas m&amp;aacute;s esperadas ser&amp;aacute; la total integraci&amp;oacute;n con Windows Phone (ya veremos si &lt;a href="http://www.pcworld.com/article/242788/windows_phone_apollo_what_we_know_so_far.html"&gt;Apollo&lt;/a&gt;, 8 o como quiera que se llame entonces), permitiendo jugar partidas simult&amp;aacute;neas en ambos dispositivos, usarlo como mando, o usar la propia Xbox (o m&amp;aacute;s bien el dispositivo sensor de movimiento &lt;a href="http://www.xbox.com/es-ES/kinect"&gt;Kinect&lt;/a&gt;) para realizar acciones t&amp;iacute;picas del tel&amp;eacute;fono.&lt;/p&gt;
&lt;p align="justify"&gt;Por ejemplo, ser&amp;aacute; posible iniciar una llamada por voz o utilizando gestures, y lo m&amp;aacute;s divertido es que &amp;eacute;stos podr&amp;aacute;n personalizarse en funci&amp;oacute;n del contacto. De este modo, podr&amp;iacute;amos hacer una llamada a casa de un amigo rasc&amp;aacute;ndonos una oreja, o levantando el pulgar. Aunque sin duda lo m&amp;aacute;s divertido puede ser cortar una llamada indeseada haciendo una &lt;a href="https://www.google.com/search?hl=en&amp;amp;q=peineta&amp;amp;gs_sm=e&amp;amp;gs_upl=41731l42598l4l42762l7l7l0l0l0l0l289l546l2-2l2l0&amp;amp;bav=on.2,or.r_gc.r_pw.,cf.osb&amp;amp;biw=1280&amp;amp;bih=968&amp;amp;wrapid=tlif132505894333610&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;tbm=isch&amp;amp;source=og&amp;amp;sa=N&amp;amp;tab=wi&amp;amp;ei=pM76Tuy8FsmYhQfas4ifAQ#um=1&amp;amp;hl=en&amp;amp;tbm=isch&amp;amp;sa=1&amp;amp;q=peineta+dedo&amp;amp;oq=peineta+dedo&amp;amp;aq=f&amp;amp;aqi=g-S3&amp;amp;aql=&amp;amp;gs_sm=e&amp;amp;gs_upl=3354l3981l0l4251l5l4l0l0l0l0l150l219l1.1l2l0&amp;amp;bav=on.2,or.r_gc.r_pw.,cf.osb&amp;amp;fp=5de1039133936c7&amp;amp;biw=1280&amp;amp;bih=968"&gt;&amp;lsquo;peineta&amp;rsquo;&lt;/a&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;En fin, un mundo nuevo de posibilidades, no cre&amp;eacute;is?&lt;/p&gt;
&lt;p align="justify"&gt;Saludos y feliz d&amp;iacute;a,&lt;/p&gt;
&lt;p&gt;&lt;iframe width="560" frameborder="0" src="http://www.youtube.com/embed/0J_Achk3_ZQ" height="315"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Source Claims Xbox 720 Arriving in 2013:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tomsguide.com/us/Microsoft-Xbox-Kinect-Gaming-Console-Windows-8,news-13537.html" title="http://www.tomsguide.com/us/Microsoft-Xbox-Kinect-Gaming-Console-Windows-8,news-13537.html"&gt;http://www.tomsguide.com/us/Microsoft-Xbox-Kinect-Gaming-Console-Windows-8,news-13537.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next Xbox to launch in 2013 according to Microsoft:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.videogamesblogger.com/2007/03/13/next-xbox-720-to-launch-in-2011-2012-according-to-microsoft.htm" title="http://www.videogamesblogger.com/2007/03/13/next-xbox-720-to-launch-in-2011-2012-according-to-microsoft.htm"&gt;http://www.videogamesblogger.com/2007/03/13/next-xbox-720-to-launch-in-2011-2012-according-to-microsoft.htm&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202344" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Futures/default.aspx">Futures</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Gadgets/default.aspx">Gadgets</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Windows+Phone/default.aspx">Windows Phone</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/xBox/default.aspx">xBox</category></item><item><title>Materiales del Webcast de ayer sobre Programación Paralela</title><link>http://geeks.ms/blogs/lfranco/archive/2011/11/30/materiales-del-webcast-de-ayer-sobre-programaci-243-n-paralela.aspx</link><pubDate>Wed, 30 Nov 2011 21:34:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201946</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=201946</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/11/30/materiales-del-webcast-de-ayer-sobre-programaci-243-n-paralela.aspx#comments</comments><description>&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Edit (07/12/2011):&lt;/strong&gt; Ya se ha publicado el webcast, por si algun insensato lo quiere ver.&lt;br /&gt; (recomiendo &amp;#39;Presentaci&amp;oacute;n de alta fidelidad de Microsoft Office Live Meeting&amp;#39;):&lt;br /&gt;&lt;a href="http://www.secondnug.com/EventosDesarrollo/tabid/57/Default.aspx"&gt;http://www.secondnug.com/EventosDesarrollo/tabid/57/Default.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:-)&lt;br /&gt;Hola de nuevo,Como ya os hab&amp;iacute;a &lt;a href="http://geeks.ms/blogs/lfranco/archive/2011/11/21/webcast-mejora-el-rendimiento-con-programaci-243-n-paralela.aspx"&gt;anunciado anteriormente&lt;/a&gt;, ayer realizamos un webcast con los chicos de &lt;a href="http://www.secondnug.com/"&gt;SecondNug&lt;/a&gt; sobre programaci&amp;oacute;n paralela.&lt;/p&gt;
&lt;p&gt;Tengo que deciros que realmente me lo pas&amp;eacute; como un enano, tanto que de hecho ya se me han ocurrido un par de ideas para otros eventos de este tipo :-D&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR"&gt;&lt;img height="337" width="454" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/banner_5F00_parallel_5F00_795FD1A8.jpg" alt="banner_parallel" border="0" title="banner_parallel" style="background-image:none;padding-left:0px;padding-right:0px;display:inline;padding-top:0px;border-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En estos momentos todav&amp;iacute;a no se puede descargar el evento grabado aunque me comentan que es cuesti&amp;oacute;n de pocas horas, de modo que en cuanto est&amp;eacute; disponible editar&amp;eacute; este post y os dejar&amp;eacute; la direcci&amp;oacute;n por si alg&amp;uacute;n insensato se lo quiere descargar.&lt;/p&gt;
&lt;p&gt;Por mi parte, como ha habido bastante gente que me ha preguntado por la presentaci&amp;oacute;n y -sobre todo- por el c&amp;oacute;digo, os dejo en enlace para que lo descargu&amp;eacute;is y jugu&amp;eacute;is con &amp;eacute;l. Y si ten&amp;eacute;is alguna &lt;a href="http://geeks.ms/blogs/lfranco/contact.aspx"&gt;mandarme un mensaje&lt;/a&gt; o mejor, un &lt;a href="http://twitter.com/#!/lluisfranco"&gt;tweet&lt;/a&gt; ;)&lt;/p&gt;
&lt;p&gt;En la soluci&amp;oacute;n he incluido algunos de los ejemplos que no di&amp;oacute; tiempo de ver, como una comparativa secuencial versus paralelo al calcular la serie de FIbonacci, o algunos ejemplos sobre las colecciones concurrentes. Particularmente os recomiendo darle un vistazo al ejemplo de uso de las BlockingCollection.&lt;/p&gt;
&lt;p&gt;No hay copyright de ning&amp;uacute;n tipo, as&amp;iacute; que pod&amp;eacute;is hacer con &amp;eacute;l lo que quer&amp;aacute;is (aunque si os apetece mandarme un jam&amp;oacute;n, no os dir&amp;eacute; que no :-P). En fin, espero que os sirva para introduciros en este apasionante mundo de la TPL.&lt;/p&gt;
&lt;p&gt;&lt;iframe scrolling="no" marginwidth="0" width="165" frameborder="0" src="https://skydrive.live.com/embed?cid=F3A970280830B5FE&amp;amp;resid=F3A970280830B5FE%21617&amp;amp;authkey=AOz-Eu8-KilU4G8" marginheight="0" height="128" title="Preview" style="padding:0;background-color:#fcfcfc;"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Si no funciona el frame de arriba tambi&amp;eacute;n pod&amp;eacute;is acceder haciendo click en este &lt;a href="https://skydrive.live.com/redir.aspx?cid=f3a970280830b5fe&amp;amp;resid=F3A970280830B5FE!617&amp;amp;parid=F3A970280830B5FE!616&amp;amp;authkey=!AM2vuRtx1HHY9Vc"&gt;enlace&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Un saludo y nos vemos,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201946" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Codigo/default.aspx">Codigo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Evento/default.aspx">Evento</category></item><item><title>Webcast: Mejora el rendimiento con Programación Paralela</title><link>http://geeks.ms/blogs/lfranco/archive/2011/11/21/webcast-mejora-el-rendimiento-con-programaci-243-n-paralela.aspx</link><pubDate>Mon, 21 Nov 2011 11:19:55 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201800</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=201800</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/11/21/webcast-mejora-el-rendimiento-con-programaci-243-n-paralela.aspx#comments</comments><description>&lt;p align="justify"&gt;El próximo 29 de Noviembre montaremos un webcast con los chicos de &lt;a href="http://www.secondnug.com/"&gt;SecondNug&lt;/a&gt; sobre programación paralela.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="banner_parallel" border="0" alt="banner_parallel" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/banner_5F00_parallel_5F00_795FD1A8.jpg" width="454" height="337" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;La idea es empezar mostrando el porqué de la programación paralela: Que es? Cómo hemos llegado a esta singularidad? Y en que casos puede sernos útil -que son muchos más de los que os podéis imaginar-. Además, como vais a ver en el webcast esto cada vez va a ir a más. Y no sólo a largo plazo… pero no os quiero avanzar mucho más, mejor ya lo veréis :-D&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/image_5F00_72601F23.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/image_5F00_thumb_5F00_105E2D18.png" width="244" height="184" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/image_5F00_00DB1B49.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/image_5F00_thumb_5F00_2CAB6F38.png" width="244" height="184" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;A partir de las 19h30 empezaremos nuestro viaje por las principales características de la nueva Task Parallel Library (TPL). Comenzaremos por una breve introducción para asentar algunos conceptos (y para picaros el gusanillo), y posteriormente pasaremos a hacer demos por un tubo. Que al fin y al cabo somos developers y es lo que nos gusta!&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="foro_parallel" border="0" alt="foro_parallel" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/foro_5F00_parallel_5F00_35B7FAB9.jpg" width="472" height="64" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Puedes registrarte aquí:    &lt;br /&gt;&lt;a title="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR" href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&amp;amp;Culture=es-AR&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Nos vemos pronto,&lt;/p&gt;  &lt;p align="justify"&gt;L&lt;/p&gt;  &lt;p align="justify"&gt;PD – Mi idea era llamarlo ‘Paralelízate o muere’ pero tal vez era un poco demasiado bestia… o no? Júzgalo tu mismo :-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201800" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Evento/default.aspx">Evento</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Webcast/default.aspx">Webcast</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SecondNug/default.aspx">SecondNug</category></item><item><title>[HowTo] Modificar cadena de conexión, la eterna pregunta</title><link>http://geeks.ms/blogs/lfranco/archive/2011/10/20/howto-modificar-cadena-de-conexi-243-n-la-eterna-pregunta.aspx</link><pubDate>Thu, 20 Oct 2011 10:27:09 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201276</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=201276</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/10/20/howto-modificar-cadena-de-conexi-243-n-la-eterna-pregunta.aspx#comments</comments><description>&lt;p align="justify"&gt;Si no la he leído 200 veces en los foros MSDN no la he leído ninguna :-) vayan unos ejemplos:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;Es posible modificar el App.config de una aplicación C# en tiempo de ejecución?&lt;/p&gt;    &lt;p align="justify"&gt;Cómo hago para cambiar los datos de conexión en tiempo de ejecución?&lt;/p&gt;    &lt;p align="justify"&gt;Cadena de conexión Dinámica, ¿cómo debo hacer esta modificación desde un windows form en el mismo aplicativo?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;Y así unas cuantas. De hecho una búsqueda me ha arrojado más de 3.000 resultados :-S&lt;/p&gt;  &lt;p align="justify"&gt;De todos modos lo que me sorprende no es tanto el alto número de veces que se hace esta pregunta, sino que cada vez que la respondo me digo a mi mismo: Haz un post y publícalo para referenciar a la gente... y siempre se me olvida :-P&lt;/p&gt;  &lt;p align="justify"&gt;Bueno, pues de hoy no pasa. Y es que curiosamente me ha llegado la misma pregunta por dos medios distintos. Uhm… casualidad? No lo creo. Sin duda es una señal divina: El &lt;a href="http://es.wikipedia.org/wiki/Pastafarismo"&gt;MEV&lt;/a&gt; me está hablando y yo -pobre mortal- debo obedecer.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;App.config y Machine.config&lt;/strong&gt;&lt;/p&gt;  &lt;p align="justify"&gt;A ver, el quid de la cuestión es que la primera vez que usamos una cadena de conexión (en un DataSource, Contexto de datos, etc.) el propio Visual Studio genera en el fichero app.config una entrada con nombre para nuestra aplicación. Esta entrada es parecida a esto:&lt;/p&gt;  &lt;div align="justify"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;clear&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;add&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;YourApp.Properties.Settings.YourAppConnectionString&amp;quot;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#ff0000;"&gt;connectionString&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Data Source=.\sqlexpress;Initial Catalog=YourDataBase;Integrated Security=True&amp;quot;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#ff0000;"&gt;providerName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Y sirve para que si alguna vez deseamos cambiar el nombre del servidor, o la base de datos, o cualquier otro atributo, lo hagamos en un único sitio.&lt;/p&gt;

&lt;p align="justify"&gt;Antes de seguir un detalle: ¿Os habéis fijado si en vuestro app.config tenéis un clear antes de la cadena de conexión? Si no lo tenéis, os aconsejo añadirlo. Este clear lo que hace es no cargar las cadenas de conexión&amp;#160; del fichero machine.config, que es común a todas las aplicaciones.&lt;/p&gt;

&lt;p align="justify"&gt;Y es que cuando se inicia una aplicación de .NET, se cargan las secciones comunes del machine.config y a continuación se añaden las propias de la aplicación definidas en el app.config.&lt;/p&gt;

&lt;p align="justify"&gt;Como por defecto en el machine.config tenemos esto:&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;add&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;LocalSqlServer&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;connectionString&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;data source=.\SQLEXPRESS;Integrated Security=SSPI;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;providerName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Si no usamos el tag clear, al ejecutar nuestra aplicación tendremos dos cadenas de conexión, y la primera será la del machine.config… y eso no nos gusta :-P&lt;/p&gt;

&lt;p align="justify"&gt;Así que asumiendo que ya habéis agregado el tag clear, vamos al turrón.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;System.Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;En este ensamblado encontraremos todo lo necesario para la gestión de nuestras cadenas de configuración (y muchas cosas más).&lt;/p&gt;

&lt;p align="justify"&gt;Lo primero es agregar una referencia a este ensamblado a nuestro proyecto:&lt;/p&gt;

&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/References_5F00_system_5F00_configuration_5F00_7BEF0FA3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="References_system_configuration" border="0" alt="References_system_configuration" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/References_5F00_system_5F00_configuration_5F00_thumb_5F00_637BA9EE.png" width="606" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Y a continuación crearemos una clase con un par de métodos para leer y guardar las cadenas de conexión en el app.config:&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ConnectionStringManager&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetConnectionString(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionStringName)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        Configuration appconfig =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        ConnectionStringSettings connStringSettings = appconfig.ConnectionStrings.ConnectionStrings[connectionStringName];&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; connStringSettings.ConnectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SaveConnectionString(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionStringName, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionString)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        Configuration appconfig =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        appconfig.ConnectionStrings.ConnectionStrings[connectionStringName].ConnectionString = connectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        appconfig.Save();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Básicamente, al primero se le pasa el nombre de la cadena de conexión a recuperar (por si tenemos varias) y nos devuelve la cadena de conexión. Al segundo se le pasa el nombre de la cadena de conexión y la nueva cadena de conexión modificada.&lt;/p&gt;

&lt;p align="justify"&gt;Para hacerlo un poco más sencillo y no tener que recordar el nombre de las cadenas de conexión, vamos a crear algunos métodos más en la clase. Uno que retorne la lista de nombres de las cadenas de conexión del fichero de configuración, y otro que retorne sólo el nombre de la primera (muy útil si sólo tenemos una).&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; List&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; GetConnectionStringNames()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    List&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; cns = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Configuration appconfig =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (ConnectionStringSettings cn &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; appconfig.ConnectionStrings.ConnectionStrings)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        cns.Add(cn.Name);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; cns;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetFirstConnectionStringName()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; GetConnectionStringNames().FirstOrDefault();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Incluso, basándonos en este último podemos crear otro que nos devuelva la primera cadena de conexión:&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetFirstConnectionString()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;strong&gt;Let’s play!&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;A partir de esta clase, trabajar con las cadenas de conexión es muy sencillo. Supongamos que tenemos un formulario similar a esto:&lt;/p&gt;

&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/form_5F00_sqlserver_5F00_settings_5F00_5E5920A5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="form_sqlserver_settings" border="0" alt="form_sqlserver_settings" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/form_5F00_sqlserver_5F00_settings_5F00_thumb_5F00_4D81502A.png" width="415" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Leer los valores de la cadena de conexión y mostrarlos es tan sencillo como esto:&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; showSavedConnectionSettings()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    SqlConnectionStringBuilder builder =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(ConnectionStringManager.GetFirstConnectionString());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    connectionServerComboBox.EditValue = builder.DataSource.ToUpper();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    connectionDatabaseComboBox.EditValue = builder.InitialCatalog.ToUpper();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (builder.IntegratedSecurity)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionAuthenticationModeRadioGroup.EditValue = 0;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionUsernameTextEdit.Text = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionPasswordTextEdit.Text = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionAuthenticationModeRadioGroup.EditValue = 1;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionUsernameTextEdit.Text = builder.UserID;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        connectionPasswordTextEdit.Text = builder.Password;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Es decir, creamos un SqlConnectionStringBuilder a partir de la primera cadena de conexión del fichero de configuración y a partir de aquí, trabajamos por separado con cada una de las partes de la cadena, accediendo a las propiedades del builder (Datasource, InitialCatalog, IntegratedSecurity, etc.). De este modo las mostramos en el form, o dónde queramos...&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;Guardando que es gerundio&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;La siguiente pregunta lógica es: ¿Y para guardar sólo uno de los valores en el fichero de configuración? El típico ejemplo es modificar el nombre del servidor al instalar en el cliente final. Para ello vamos a usar también un builder, y vamos a ampliar la clase anterior con algunos métodos más. Para obtener los valores de las propiedades de la cadena de conexión y para guardarlos:&lt;/p&gt;

&lt;p align="justify"&gt;Obtener valores de propiedades de la cadena de conexión:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetSqlServerServerName()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cs != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        SqlConnectionStringBuilder builder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(cs);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.DataSource;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetSqlServerDatabaseName()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cs != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        SqlConnectionStringBuilder builder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(cs);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.InitialCatalog;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetSqlServerUserName()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cs != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        SqlConnectionStringBuilder builder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(cs);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.UserID;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetSqlServerPassword()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cs != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        SqlConnectionStringBuilder builder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(cs);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.Password;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;? GetSqlServerIntegratedSecurity()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = GetConnectionString(GetFirstConnectionStringName());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cs != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        SqlConnectionStringBuilder builder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(cs);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.IntegratedSecurity;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Guardar valores de propiedades en la cadena de conexión:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SetConnectionStringServerName(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionString, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; serverName)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    SqlConnectionStringBuilder builder =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(connectionString);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.DataSource = serverName;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.ConnectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SetConnectionStringAutenticationIntegrated(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionString)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    SqlConnectionStringBuilder builder =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(connectionString);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.IntegratedSecurity = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.ConnectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SetConnectionStringAutenticationSQLServer(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionString, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; username, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; password)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    SqlConnectionStringBuilder builder =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(connectionString);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.IntegratedSecurity = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.UserID = username;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.Password = password;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.ConnectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SetConnectionStringDatabaseName(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionString, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; databaseName)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    SqlConnectionStringBuilder builder =&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnectionStringBuilder(connectionString);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    builder.InitialCatalog = databaseName;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builder.ConnectionString;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Así pues, para cambiar el nombre del servidor en el app.config bastaría con:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Leer la cadena de conexión actual&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Cambiar el nombre del server &lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Volver a guardar la cadena de conexión&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; cs = ConnectionStringManager.GetFirstConnectionString();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; newConStr = ConnectionStringManager.SetConnectionStringServerName(cs, &lt;span style="color:#006080;"&gt;&amp;quot;MyNewServer&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;ConnectionStringManager.SaveConnectionString(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ConnectionStringManager.GetFirstConnectionStringName(), newConStr);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Me han quedado bastantes cosas en el tintero (recuperar los servidores SQL Server de nuestra red local, mostrar las bases de datos de un server, o crear un formulario para el usuario final). Si hay tiempo y pensáis que es un tema de interés lo veremos en futuros posts.&lt;/p&gt;

&lt;p align="justify"&gt;Nos vemos! :-D&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201276" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Config/default.aspx">Config</category></item><item><title>[HowTo] Obtener fechas de principio y final de mes… y de trimestre</title><link>http://geeks.ms/blogs/lfranco/archive/2011/10/05/howto-obtener-fechas-de-principio-y-final-e-mes-y-de-trimestre.aspx</link><pubDate>Wed, 05 Oct 2011 02:22:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201000</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=201000</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/10/05/howto-obtener-fechas-de-principio-y-final-e-mes-y-de-trimestre.aspx#comments</comments><description>&lt;p&gt;Vale, lo se. Es una chorrada :-)&lt;/p&gt;  &lt;p&gt;Pero es una de esas cosas que no puedes creer que no está implementado en el framework ‘de fábrica’, y si lo está debe estar escondido porque yo no lo he encontrado. Y la cuestión es que ayer necesitaba calcular (a partir de una fecha) las fechas de inicio y final de mes, así como las fechas de inicio y final de trimestre.&lt;/p&gt;  &lt;p&gt;Aquí está el código por si alguien se encuentra con el mismo problema:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; BaseTypesExtensions&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; GetQuarter(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; DateTime d)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; ((d.Month - 1) / 3) + 1;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; DateTime GetMonthFirstDate(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; DateTime d)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DateTime(d.Year, d.Month, 1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; DateTime GetMonthLastDate(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; DateTime d)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; d.GetMonthFirstDate().AddMonths(1).AddDays(-1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; DateTime GetQuarterFirstDate(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; DateTime d)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DateTime(d.Year, (d.GetQuarter() * 3) - 2, 1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; DateTime GetQuarterLastDate(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; DateTime d)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; d.GetQuarterFirstDate().AddMonths(3).AddDays(-1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Y lo usaríamos de este modo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var basedate = DateTime.Today.AddYears(-1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 23; i++)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    basedate = basedate.AddMonths(1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var logline = &lt;span style="color:#006080;"&gt;&amp;quot;Date: {0}, Month {1}-{2}, Quarter: {3}-{4}&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Console.WriteLine(logline, basedate.ToShortDateString(),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        basedate.GetMonthFirstDate().ToShortDateString(), &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        basedate.GetMonthLastDate().ToShortDateString(),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        basedate.GetQuarterFirstDate().ToShortDateString(), &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        basedate.GetQuarterLastDate().ToShortDateString());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Produciendo este resultado:&lt;/p&gt;

&lt;p&gt;Date: 05/11/2010, Month 01/11/2010-30/11/2010, Quarter: 01/10/2010-31/12/2010 
  &lt;br /&gt;Date: 05/12/2010, Month 01/12/2010-31/12/2010, Quarter: 01/10/2010-31/12/2010 

  &lt;br /&gt;Date: 05/01/2011, Month 01/01/2011-31/01/2011, Quarter: 01/01/2011-31/03/2011 

  &lt;br /&gt;Date: 05/02/2011, Month 01/02/2011-28/02/2011, Quarter: 01/01/2011-31/03/2011 

  &lt;br /&gt;Date: 05/03/2011, Month 01/03/2011-31/03/2011, Quarter: 01/01/2011-31/03/2011 

  &lt;br /&gt;Date: 05/04/2011, Month 01/04/2011-30/04/2011, Quarter: 01/04/2011-30/06/2011 

  &lt;br /&gt;Date: 05/05/2011, Month 01/05/2011-31/05/2011, Quarter: 01/04/2011-30/06/2011 

  &lt;br /&gt;Date: 05/06/2011, Month 01/06/2011-30/06/2011, Quarter: 01/04/2011-30/06/2011 

  &lt;br /&gt;Date: 05/07/2011, Month 01/07/2011-31/07/2011, Quarter: 01/07/2011-30/09/2011 

  &lt;br /&gt;Date: 05/08/2011, Month 01/08/2011-31/08/2011, Quarter: 01/07/2011-30/09/2011 

  &lt;br /&gt;Date: 05/09/2011, Month 01/09/2011-30/09/2011, Quarter: 01/07/2011-30/09/2011 

  &lt;br /&gt;Date: 05/10/2011, Month 01/10/2011-31/10/2011, Quarter: 01/10/2011-31/12/2011 

  &lt;br /&gt;Date: 05/11/2011, Month 01/11/2011-30/11/2011, Quarter: 01/10/2011-31/12/2011 

  &lt;br /&gt;Date: 05/12/2011, Month 01/12/2011-31/12/2011, Quarter: 01/10/2011-31/12/2011 

  &lt;br /&gt;Date: 05/01/2012, Month 01/01/2012-31/01/2012, Quarter: 01/01/2012-31/03/2012 

  &lt;br /&gt;Date: 05/02/2012, Month 01/02/2012-29/02/2012, Quarter: 01/01/2012-31/03/2012&lt;/p&gt;

&lt;p&gt;Saludos,&lt;/p&gt;



&lt;p&gt;PD – Thx al colega &lt;a href="http://geeks.ms/blogs/omarvr"&gt;Omar del valle&lt;/a&gt; por sugerir una aproximación mucho más sencilla para GetQuarter ;-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201000" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Tip/default.aspx">Tip</category></item><item><title>MVP por noveno año y cambio de categoría :-D</title><link>http://geeks.ms/blogs/lfranco/archive/2011/10/01/mvp-por-noveno-a-241-o-y-cambio-de-categor-237-a-d.aspx</link><pubDate>Sat, 01 Oct 2011 14:30:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200884</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200884</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/10/01/mvp-por-noveno-a-241-o-y-cambio-de-categor-237-a-d.aspx#comments</comments><description>&lt;p&gt;:-)&lt;br /&gt;Hola a todos!&lt;/p&gt;
&lt;p&gt;Un post cortito que estoy de fin de semana.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/mvplogohor_5F00_4840ACD1.png"&gt;&lt;img height="94" width="227" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/mvplogohor_5F00_thumb_5F00_70FC121A.png" alt="mvplogohor" border="0" title="mvplogohor" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Acabo de recibir un correo (o m&amp;aacute;s bien deber&amp;iacute;a decir EL correo) que muchos de nosotros esperamos el 1 de Octubre: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Enhorabuena. Nos complace presentarle el programa de nombramiento MVP de Microsoft&amp;reg; de 2011. Este nombramiento se concede a los l&amp;iacute;deres excepcionales de la comunidad t&amp;eacute;cnica que comparten de forma activa su experiencia de alta calidad y de la vida real con otras personas. Le agradecemos especialmente la contribuci&amp;oacute;n que ha realizado en las comunidades t&amp;eacute;cnicas en el &amp;aacute;rea de Visual C# a lo largo del pasado a&amp;ntilde;o.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;El correo de la fatalidad. El correo del reconocimiento -o no- como Microsoft MVP para el pr&amp;oacute;ximo a&amp;ntilde;o. Y parece que se han vuelto a equivocar... por que alguien ha decidido que merezco estar otro a&amp;ntilde;o llevando ese pin tan chulo que nos regalan, y rodeado de toda esa gente tan cojonuda. Y perdonar que lo diga tan claro, pero realmente es as&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Por encima de todo (reconocimiento, beneficios, dinero y mujeres) lo mejor de este programa es la gente. Siendo MVP conoces gente que profesionalmente son unos monstruos (de buenos), y adem&amp;aacute;s ves c&amp;oacute;mo estos t&amp;iacute;os dedican un % enorme de su tiempo a ayudar y colaborar desinteresadamente, haciendo crecer la comunidad.&amp;nbsp;Que a su vez es la madre de todos los MVPs y de muchos otros, ya que hay gente muuuuy buena y preparada que todav&amp;iacute;a no ha tenido la oportunidad de entrar en este programa.&lt;/p&gt;
&lt;p&gt;Adem&amp;aacute;s, este a&amp;ntilde;o si no he le&amp;iacute;do mal el correo se ha reconocido mi contribuci&amp;oacute;n al area de C#, en lugar de VB como hasta ahora. Supongo que es normal, ya que hace unos cuantos a&amp;ntilde;os que no toco nada de VB, pero de todos modos se agradece.&lt;/p&gt;
&lt;p&gt;Much&amp;iacute;simas gracias a todos. De verdad :-)&lt;/p&gt;
&lt;p&gt;Ahora permitirme copypastear unas fotos del post del a&amp;ntilde;o pasado... que no tengo material aqu&amp;iacute; d&amp;oacute;nde estoy de weekend&amp;nbsp;:-P&lt;/p&gt;
&lt;p&gt;&amp;lt;copypaste&amp;gt;&lt;/p&gt;
&lt;p align="justify"&gt;Aqu&amp;iacute; ten&amp;eacute;is algunos momentos de estos a&amp;ntilde;os:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1608_5F00_0A839F48.jpg"&gt;&lt;img height="164" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1608_5F00_thumb_5F00_0EE9FA42.jpg" alt="DCP_1608" border="0" title="DCP_1608" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1652_5F00_0DA56163.jpg"&gt;&lt;img height="164" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1652_5F00_thumb_5F00_5FA7E8DD.jpg" alt="DCP_1652" border="0" title="DCP_1652" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1629_5F00_0BE46FC2.jpg"&gt;&lt;img height="164" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/DCP_5F00_1629_5F00_thumb_5F00_3CF38495.jpg" alt="DCP_1629" border="0" title="DCP_1629" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010037_5F00_37386AEF.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010037_5F00_thumb_5F00_6EFA8945.jpg" alt="P1010037" border="0" title="P1010037" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010059_5F00_58583AFE.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010059_5F00_thumb_5F00_3D2F4623.jpg" alt="P1010059" border="0" title="P1010059" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010029_5F00_268CF7DC.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/P1010029_5F00_thumb_5F00_791B3C3E.jpg" alt="P1010029" border="0" title="P1010029" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb1_5F00_509C5A2A.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb1_5F00_thumb_5F00_13B7B28B.jpg" alt="fb1" border="0" title="fb1" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb2_5F00_7D156443.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb2_5F00_thumb_5F00_7615B1BE.jpg" alt="fb2" border="0" title="fb2" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb3_5F00_2D7BC2ED.jpg"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb3_5F00_thumb_5F00_111E5B00.jpg" alt="fb3" border="0" title="fb3" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb6_5F00_0F6D8F2C.png"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb6_5F00_thumb_5F00_5B752773.png" alt="fb6" border="0" title="fb6" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;MARGIN:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb4_5F00_48244B07.png"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb4_5F00_thumb_5F00_687B1952.png" alt="fb4" border="0" title="fb4" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;MARGIN:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb5_5F00_47C429E0.png"&gt;&lt;img height="184" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fb5_5F00_thumb_5F00_7639E728.png" alt="fb5" border="0" title="fb5" class="wlDisabledImage" style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;Son simplemente algunos momentos escogidos al azar entre tantos buenos momentos. Encontrar&amp;eacute;is a algunos de los que ya no est&amp;aacute;n, y tambi&amp;eacute;n ver&amp;eacute;is a algunos que casi no se reconocen, jejeje&amp;hellip; A ver que d&amp;iacute;a me pongo a revisar m&amp;aacute;s a fondo los cientos de archivos de fotos que tengo (sobretodo de los primeros a&amp;ntilde;os), seguro que aparecen aut&amp;eacute;nticas &amp;lsquo;perlas&amp;rsquo;:-)&lt;/p&gt;
&lt;p align="justify"&gt;Un abrazo enorme a todos, los que son MVP, los que no, y en general a todos aquellos que dedican su tiempo a hacer m&amp;aacute;s grande la comunidad. Todos son MVP, tengan o no tengan la distinci&amp;oacute;n. Chavales, entre todos estamos contribuyendo a hacer algo grande.&lt;/p&gt;
&lt;p&gt;&amp;lt;/copypaste&amp;gt;&lt;/p&gt;
&lt;p&gt;PD - Tengo que deciros que cada a&amp;ntilde;o que pasa lo llevo mejor, hoy s&amp;oacute;lo hab&amp;iacute;a entrado a consultar el correo 3 veces :-D&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200884" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/MVP/default.aspx">MVP</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Award/default.aspx">Award</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2011/default.aspx">2011</category></item><item><title>ParseTo: Un TryParse para unirlos a todos en las tinieblas</title><link>http://geeks.ms/blogs/lfranco/archive/2011/09/30/parseto-un-tryparse-para-unirlos-a-todos-en-las-tinieblas.aspx</link><pubDate>Fri, 30 Sep 2011 11:11:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200853</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200853</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/09/30/parseto-un-tryparse-para-unirlos-a-todos-en-las-tinieblas.aspx#comments</comments><description>&lt;p&gt;MUAHAHA!!! :-)&lt;/p&gt;  &lt;p&gt;¿Quién no conoce los métodos &lt;a href="http://msdn.microsoft.com/en-us/library/system.int32.parse.aspx"&gt;Parse&lt;/a&gt; y &lt;a href="http://msdn.microsoft.com/en-us/library/c846ws90.aspx"&gt;TryParse&lt;/a&gt;? &lt;/p&gt;  &lt;p&gt;Estos métodos son comúnmente usados para verificar si una cadena puede ser convertida a un número, fecha, etc.&lt;/p&gt;  &lt;p align="justify"&gt;El problema con éstos métodos es que pertenecen a los tipos base de .NET (int, long, decimal, DateTime), de modo que cada vez que tenemos que parsear un valor hay que utilizar un método distinto en una clase distinta. Además, en el caso de &lt;a href="http://msdn.microsoft.com/en-us/library/system.int32.parse.aspx"&gt;Parse&lt;/a&gt; si intentamos parsear un valor incorrecto (por ejemplo “123,45” a int) se produce una excepción en tiempo de ejecución, que es algo muy costoso en términos de rendimiento. Y de la sintaxis de &lt;a href="http://msdn.microsoft.com/en-us/library/c846ws90.aspx"&gt;TryParse&lt;/a&gt; mejor no hablar, han corrido ríos de tinta acerca de sus peculiaridades:&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;Ejemplos:&lt;/strong&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; s = &lt;span style="color:#006080;"&gt;&amp;quot;123,45&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i1 = &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.Parse(s); &lt;span style="color:#008000;"&gt;//Runtime exception (FormatException)!&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i2;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.TryParse(s, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; i2))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//Parse ok! Use i2 for something...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;El tema es que recientemente he tenido que hacer un uso bastante intenso de estos métodos para parsear cantidades ingentes de datos, así que he decidido buscar una implementación más cómoda y a ser posible con el mismo rendimiento que &lt;a href="http://msdn.microsoft.com/en-us/library/c846ws90.aspx"&gt;TryParse&lt;/a&gt;, o al menos parecido.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;Primeras aproximaciones:&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Lo primero que he pensado es -cómo no- en usar Generics :-) Peeeero resulta que &lt;a href="http://msdn.microsoft.com/en-us/library/c846ws90.aspx"&gt;TryParse&lt;/a&gt; no está declarado en ninguna interfaz que compartan los tipos base de .NET, de modo que esta aproximación no nos vale.&lt;/p&gt;

&lt;p align="justify"&gt;Mi segunda aproximación ha sido usar los &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx"&gt;TypeConverter&lt;/a&gt; de .NET, que ya había usado en otras ocasiones:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T ConvertTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; ConvertTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, CultureInfo.CurrentCulture);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T ConvertTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, CultureInfo cultureInfo)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var typeConverter = TypeDescriptor.GetConverter(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(T));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (typeConverter.CanConvertFrom(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;)))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (T)typeConverter.ConvertFromString(&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, cultureInfo, &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Esta solución es bastante elegante ya que permite tener un sólo método extensor del tipo string y pasarle el tipo al que debe ser convertido. Además está sobrecargado para poder aceptar la cultura como argumento:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var value1 = &lt;span style="color:#006080;"&gt;&amp;quot;123456&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(value1.ConvertTo&amp;lt;&lt;span style="color:#0000ff;"&gt;long&lt;/span&gt;&amp;gt;());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(value1.ConvertTo&amp;lt;&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;&amp;gt;());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(value1.ConvertTo&amp;lt;&lt;span style="color:#0000ff;"&gt;float&lt;/span&gt;&amp;gt;());&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Sin embargo esta aproximación adolece de un problema de rendimiento. Por un lado hay que crear un &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx"&gt;TypeConverter&lt;/a&gt; y por el otro, el único modo de saber si la conversión en factible es forzándola e interceptando la excepción en runtime. Para que os hagáis una idea, si se ejecuta 100.000 veces tarda el doble que un TryParse por cada valor correcto, lo cual es... aceptable. Pero si el valor es incorrecto y se produce una excepción tarda del orden de 100 veces más, de modo que esta opción sólo es válida para parsear datos ocasionalmente.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;La definitiva: (versión 1):&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Entretanto, se me ha ocurrido que se podría crear un método extensor de la clase string (al fin y al cabo nuestro propósito es parsear cadenas) al cual se le pase el método encargado de hacer el parseo de la cadena. Una paranoia, vamos… pero una vez implementado me gusta como ha quedado:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; ParseToDelegate&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; T result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; ParseToCultureDelegate&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    NumberStyles style, IFormatProvider provider, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; T result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T? ParseTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ParseToDelegate&amp;lt;T&amp;gt; method) &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;struct&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    T result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (String.IsNullOrWhiteSpace(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (method(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; result)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Observar que se usa un delegado a través del cual se informará el método a usar para realizar el parseo, y además, en caso de no poder realizar la conversión se devuelve un null (que a mi me basta y me sobra para saber si la conversión se ha realizado con éxito).&lt;/p&gt;

&lt;p&gt;De este modo para usarlo, basta con:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var s = &lt;span style="color:#006080;"&gt;&amp;quot;1234,567&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(s.ParseTo&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.TryParse)); &lt;span style="color:#008000;"&gt;//Error. Returns null&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(s.ParseTo&amp;lt;&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;.TryParse)); &lt;span style="color:#008000;"&gt;//Ok&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var d = &lt;span style="color:#006080;"&gt;&amp;quot;14/05/2011 19:45&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(d.ParseTo&amp;lt;DateTime&amp;gt;(DateTime.TryParse)); &lt;span style="color:#008000;"&gt;//Ok&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var g = Guid.NewGuid().ToString();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(g.ParseTo&amp;lt;Guid&amp;gt;(Guid.TryParse)); //Ok&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Genial! :-D&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;El problema de la primera versión:&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Cuando he querido agregar el soporte para múltiples culturas pasándole un argumento de tipo CultureInfo me encuentro con esto:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; TryParse(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; s, NumberStyles style, IFormatProvider provider, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; TryParse(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; s, IFormatProvider provider, DateTimeStyles styles, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; DateTime result);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Las firmas del método TryParse de los tipos numéricos y fechas no coinciden! Y es que además tienen los argumentos en distinto orden… WTF! :-S&lt;/p&gt;

&lt;p&gt;Pero a que gili…s se le ha ocurrido diseñarlo de este modo?&lt;/p&gt;

&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/tonto_5F00_05E49689.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="tonto" border="0" alt="tonto" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/tonto_5F00_thumb_5F00_325DA0A2.jpg" width="244" height="184" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;Pensemos en ello en fin de semana…&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;…y el lunes (si ha habido suerte) publicaremos la o las posibles soluciones. De momento, buen fin de semana! :-P&lt;/p&gt;

&lt;p align="justify"&gt;-TO BE CONTINUED-&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;Update (05/10/2011)&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Es martes y todavía no he podido volver a ponerme con el tema :-(&lt;/p&gt;

&lt;p align="justify"&gt;De momento la solución que encontré no me agrada demasiado, y se trata de crear métodos aparte para realizar el parseo utilizando la cultura deseada.&lt;/p&gt;

&lt;p align="justify"&gt;El código quedaría de este modo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; ParseNumberWithCultureToDelegate&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    NumberStyles style, IFormatProvider provider, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; T result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; ParseDateTimeWithCultureDelegate&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    IFormatProvider provider, DateTimeStyles styles, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; T result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T? ParseNumberWithCultureTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ParseNumberWithCultureToDelegate&amp;lt;T&amp;gt; method, CultureInfo cultureInfo) &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;struct&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    T result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (String.IsNullOrWhiteSpace(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (method(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, NumberStyles.Any, &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        cultureInfo.NumberFormat, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; result)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T? ParseDateTimeWithCultureTo&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ParseDateTimeWithCultureDelegate&amp;lt;T&amp;gt; method, CultureInfo cultureInfo) &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;struct&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    T result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (String.IsNullOrWhiteSpace(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (method(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, cultureInfo, DateTimeStyles.None,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; result)) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; result;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Y se utilizaría de este modo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var n = &lt;span style="color:#006080;"&gt;&amp;quot;123,45&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(n.ParseTo&amp;lt;&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;.TryParse)); &lt;span style="color:#008000;"&gt;//123.45&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(n.ParseNumberWithCultureTo&amp;lt;&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt;.TryParse, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CultureInfo(&lt;span style="color:#006080;"&gt;&amp;quot;en-US&amp;quot;&lt;/span&gt;))); &lt;span style="color:#008000;"&gt;//12345&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;var d = &lt;span style="color:#006080;"&gt;&amp;quot;02/05/2011 16:45&amp;quot;&lt;/span&gt;;            &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(d.ParseTo&amp;lt;DateTime&amp;gt;(DateTime.TryParse)); &lt;span style="color:#008000;"&gt;//02/05/2011 16:45&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;Console.WriteLine(d.ParseDateTimeWithCultureTo&amp;lt;DateTime&amp;gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    DateTime.TryParse, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CultureInfo(&lt;span style="color:#006080;"&gt;&amp;quot;en-US&amp;quot;&lt;/span&gt;))); &lt;span style="color:#008000;"&gt;//05/02/2011 16:45&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Funciona perfectamente y el rendimiento es entre 50 y 100 veces más rápido que el uso del TypeConverter (entre 1,1 y 1,4 veces el uso del TryParse tradicional).&lt;/p&gt;

&lt;p align="justify"&gt;En fin, a ver si saco tiempo y encuentro una solución más ‘elegante’ que ésta. Y si alguno de vosotros tiene alguna idea, será muy bien recibida ;-)&lt;/p&gt;

&lt;p align="justify"&gt;Nos vemos,&lt;/p&gt;

&lt;p&gt;PD - Hay algunas alternativas que ni siquiera he evaluado (como el uso de Reflection) ya que mi principal requisito es ofrecer un buen rendimiento.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200853" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Generics/default.aspx">Generics</category></item><item><title>[HowTo] Crear una pantalla que espere la conclusión de una tarea larga (con cancelación)</title><link>http://geeks.ms/blogs/lfranco/archive/2011/09/29/howto-crear-una-pantalla-que-espere-la-conclusi-243-n-de-una-tarea-larga-con-cancelaci-243-n.aspx</link><pubDate>Thu, 29 Sep 2011 09:52:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200835</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200835</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/09/29/howto-crear-una-pantalla-que-espere-la-conclusi-243-n-de-una-tarea-larga-con-cancelaci-243-n.aspx#comments</comments><description>&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreen_5F00_5E17F4EA.png"&gt;&lt;img height="352" width="451" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreen_5F00_thumb_5F00_7BA9CFE9.png" alt="WaitForTaskScreen" border="0" title="WaitForTaskScreen" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;En el &lt;a href="http://geeks.ms/blogs/lfranco/archive/2011/09/28/howto-crear-una-pantalla-que-espere-la-conclusi-243-n-de-una-tarea-larga.aspx"&gt;post anterior&lt;/a&gt; vimos un ejemplo de c&amp;oacute;mo crear una ventana que espere la conclusi&amp;oacute;n de una tarea. Si bien este ejemplo cubr&amp;iacute;a sobradamente el objetivo, dejamos abierta la puerta a la posibilidad de que dicha tarea pudiese ser cancelada por petici&amp;oacute;n del usuario, pulsando el bot&amp;oacute;n &amp;lsquo;cancel&amp;rsquo; de la ventana.&lt;/p&gt;
&lt;p align="justify"&gt;Si se hizo de este modo fue para evitar complicar en exceso el post, ya que el objetivo inicial era simplemente &amp;ldquo;mostrar una ventana mientras durase el proceso&amp;rdquo;.&lt;/p&gt;
&lt;p align="justify"&gt;Tras publicar el post y ver algunas de las reacciones en el &lt;a href="http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/56fd68a6-2e9f-4639-a9a6-621b9f32c56d/?prof=required"&gt;hilo del foro de C#&lt;/a&gt; de MSDN (gracias &lt;a href="http://social.msdn.microsoft.com/profile/pedro%20hurtado/"&gt;Pedro&lt;/a&gt; por tu idea), he decidido ampliar el proyecto de ejemplo ofreciendo al usuario la posibilidad de cancelar REALMENTE la tarea, utilizando para ello un &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx"&gt;CancellationToken&lt;/a&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx"&gt;CancellationToken&lt;/a&gt; es una estructura nueva del .NET Framework 4.0 (as&amp;iacute; como toda la TPL en s&amp;iacute;), y permite la cancelaci&amp;oacute;n de un proceso as&amp;iacute;ncrono. Es com&amp;uacute;nmente usada cuando deseamos propagar una notificaci&amp;oacute;n de cancelaci&amp;oacute;n hacia arriba, por ejemplo, hacia el m&amp;eacute;todo que est&amp;aacute; siendo ejecutado como en nuestro caso.&lt;/p&gt;
&lt;p align="justify"&gt;Para ello necesitamos crear previamente un &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource.aspx"&gt;CancellationTokenSource&lt;/a&gt;, que es el objeto que contiene el token de cancelaci&amp;oacute;n y que adem&amp;aacute;s nos va a permitir cancelar la tarea. Posteriormente este objeto nos proporcionar&amp;aacute; el token de cancelaci&amp;oacute;n, que usaremos en la llamada a la tarea. Pero vamos a verlo mejor con un poco de c&amp;oacute;digo:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;En el formulario de espera:&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Aparecen algunos cambios, por ejemplo debemos modificar la firma de la propiedad ActionToExecute para que acepte un m&amp;eacute;todo que contenga un par&amp;aacute;metro de tipo CancellationToken. Este par&amp;aacute;metro ser&amp;aacute; usado por el m&amp;eacute;todo para saber si se ha cancelado y actuar en consecuencia. De paso aprovecharemos para declarar el &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource.aspx"&gt;CancellationTokenSource&lt;/a&gt;.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Action&amp;lt;CancellationToken&amp;gt; ActionToExecute { get; set; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;CancellationTokenSource cancelTokenSource = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Nota importante: En el proyecto anterior, el bot&amp;oacute;n &amp;lsquo;cancel&amp;rsquo; no ten&amp;iacute;a c&amp;oacute;digo asociado. Simplemente ten&amp;iacute;a establecida la propiedad DialogResult en Cancel, de modo que al pulsarlo cerraba autom&amp;aacute;ticamente la ventana y devolv&amp;iacute;a el valor Cancel a su llamador. En el proyecto actual como s&amp;iacute; que nos interesa controlar el cierre de la ventana, es necesario establecer la propiedad DialogResult en None e interceptar su evento:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;closeButton.Click += closeButton_Click;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; closeButton_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Aqu&amp;iacute; m&amp;aacute;s adelante cancelaremos la tarea y devolveremos un valor DialogResult = Cancel.&lt;/p&gt;
&lt;p align="justify"&gt;Ahora vamos a centrarnos en la creaci&amp;oacute;n y ejecuci&amp;oacute;n de la tarea as&amp;iacute;ncrona:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; fSplashScreen_Shown(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    titleLabel.Text = Title;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    messageLabel.Text = Message;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    pictureBox.Image = Picture;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    Task.Factory.StartNew(() =&amp;gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        ActionToExecute(cancelTokenSource.Token)).ContinueWith((t) =&amp;gt; taskCompleted());&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Como veis en realidad no hay demasiados cambios, lo &amp;uacute;nico es que en la llamada a StartNew obtenemos el token de cancelaci&amp;oacute;n de su &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource.aspx"&gt;CancellationTokenSource&lt;/a&gt;, y cuando posteriormente &amp;eacute;sta sea cancelada por el usuario, el token ser&amp;aacute; propagado hasta el m&amp;eacute;todo que se est&amp;aacute; ejecutando, permitiendo su cancelaci&amp;oacute;n.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Hablando del m&amp;eacute;todo, que modificaciones hay que realizar?&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;El m&amp;eacute;todo original era este:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomeHardWork()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 50; i++)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        Console.WriteLine(i);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        Thread.Sleep(100);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }            &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Y el nuevo quedar&amp;iacute;a as&amp;iacute;:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomeHardWorkWithCancellation(CancellationToken cancelToken)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 50; i++)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            cancelToken.ThrowIfCancellationRequested();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            Console.WriteLine(i);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            Thread.Sleep(100);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception ex)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        MessageBox.Show(ex.Message, Application.ProductName, &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Como dec&amp;iacute;amos antes, este m&amp;eacute;todo recibe un par&amp;aacute;metro de tipo CancellationToken y lo &amp;uacute;nico que hay que hacer es lanzar una excepci&amp;oacute;n en caso que haya sigo solicitada una cancelaci&amp;oacute;n (de ah&amp;iacute; que se envuelva el c&amp;oacute;digo dentro de un bloque try-catch).&lt;/p&gt;
&lt;p align="justify"&gt;Nada m&amp;aacute;s. Una s&amp;oacute;lo l&amp;iacute;nea y el pertinente bloque de intercepci&amp;oacute;n de errores&amp;hellip; y voil&amp;aacute;! No os parece bonito y elegante? :-)&lt;/p&gt;
&lt;p align="justify"&gt;Por cierto, en caso que no se desee lanzar una excepci&amp;oacute;n es posible que os interese preguntar por el valor de la propiedad &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource.iscancellationrequested.aspx"&gt;IsCancellationRequested&lt;/a&gt; y elegir vosotros mismos la acci&amp;oacute;n m&amp;aacute;s apropiada.&lt;/p&gt;
&lt;p align="justify"&gt;Volvamos al formulario de espera y completemos el c&amp;oacute;digo que falta. Primeramente el c&amp;oacute;digo del bot&amp;oacute;n &amp;lsquo;cancel&amp;rsquo;, encargado de cancelar realmente la tarea:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; closeButton_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    DialogResult = DialogResult.Cancel;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    cancelTokenSource.Cancel();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    releaseCancellationTokenSource();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; releaseCancellationTokenSource()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cancelTokenSource != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        cancelTokenSource.Dispose();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        cancelTokenSource = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Y por &amp;uacute;ltimo, agregar una l&amp;iacute;nea para liberar tambi&amp;eacute;n el token al finalizar con &amp;eacute;xito la tarea:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; taskCompleted()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (InvokeRequired)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            Close();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            DialogResult = DialogResult.OK;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }));&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    releaseCancellationTokenSource();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Y con esto y un bizcocho, hemos terminado! Espero que os haya gustado :-D&lt;/p&gt;
&lt;p align="justify"&gt;Muchas gracias de nuevo a Pedro Hurtado y a toda la gente del &lt;a href="http://social.msdn.microsoft.com/Forums/es-ES/vcses/threads"&gt;foro de C# en MSDN&lt;/a&gt; :-)&lt;/p&gt;
&lt;p&gt;Os dejo tambi&amp;eacute;n el mini proyecto de ejemplo por si quer&amp;eacute;is jugar un rato:&lt;/p&gt;
&lt;p&gt;&lt;iframe scrolling="no" marginwidth="0" frameborder="0" src="https://skydrive.live.com/embedicon.aspx/MSDN%20Samples/TestWaitForTaskScreenWithCancellation.zip?cid=f3a970280830b5fe&amp;amp;sc=documents" marginheight="0" title="Preview" style="background-color:#fcfcfc;width:98px;height:115px;padding:0px;"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Nos vemos,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200835" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Ejemplo/default.aspx">Ejemplo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/MSDN+Forums/default.aspx">MSDN Forums</category></item><item><title>[HowTo] Crear una pantalla que espere la conclusión de una tarea larga</title><link>http://geeks.ms/blogs/lfranco/archive/2011/09/28/howto-crear-una-pantalla-que-espere-la-conclusi-243-n-de-una-tarea-larga.aspx</link><pubDate>Wed, 28 Sep 2011 13:49:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200795</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200795</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/09/28/howto-crear-una-pantalla-que-espere-la-conclusi-243-n-de-una-tarea-larga.aspx#comments</comments><description>&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreen_5F00_07568375.png"&gt;&lt;img height="352" width="451" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreen_5F00_thumb_5F00_72F0BDE9.png" alt="WaitForTaskScreen" border="0" title="WaitForTaskScreen" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Otro post en respuesta a una pregunta bastante habitual en los foros MSDN: &amp;ldquo;Mi frmPrincipal ejecuta una funci&amp;oacute;n (no tengo el tiempo preciso) y mientras realiza esto quiero que aparezca una ventana &amp;hellip; que impida el acceso al frmPrincipal y una vez que se termine de ejecutar la funci&amp;oacute;n, desaparezca frmMensaje.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p align="justify"&gt;La verdad es que hay un mont&amp;oacute;n de posibles soluciones. Desde el uso del componente &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx"&gt;BackgroundWorker&lt;/a&gt; (la opci&amp;oacute;n m&amp;aacute;s sencilla pero la que menos me gusta :-P) hasta los futuros &lt;strong&gt;async&lt;/strong&gt; y &lt;strong&gt;await&lt;/strong&gt; que &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2010/10/28/asynchrony-in-c-5-part-one.aspx"&gt;vendr&amp;aacute;n con C# 5&lt;/a&gt;, pasando por los cl&amp;aacute;sicos threads de toda la vida o las tareas que se introdujeron con la TPL en Visual Studio 2010.&lt;/p&gt;
&lt;p align="justify"&gt;Para este ejemplo vamos a utilizar &amp;eacute;sta &amp;uacute;ltima aproximaci&amp;oacute;n, ya que de las otras hay millones de ejemplos de todos los tipos y colores. Adem&amp;aacute;s, puede servir como -sencillo- ejercicio de uso de la clase &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx"&gt;Task&lt;/a&gt;, para que qui&amp;eacute;n no la conozca vaya introduci&amp;eacute;ndose en el &lt;a href="http://youtu.be/2axRAjrXDME?hd=1"&gt;maravilloso mundo de la programaci&amp;oacute;n paralela&lt;/a&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;Primeramente vamos a crear un formulario con un t&amp;iacute;tulo, un mensaje y una barra de progreso de tipo marquesina, ya que como dice el enunciado &amp;ldquo;no se conoce de antemano la duraci&amp;oacute;n de la tarea a ejecutar&amp;rdquo;. Y para comprobar que la tarea se ejecuta en segundo plano (en realidad en paralelo si hay m&amp;aacute;s de un core en el procesador) tambi&amp;eacute;n a&amp;ntilde;adiremos un bot&amp;oacute;n para poder cerrar la ventana.&lt;/p&gt;
&lt;p align="justify"&gt;Aviso: Este bot&amp;oacute;n &amp;uacute;nicamente sirve para cerrar la ventana y retornar a la ventana principal.&amp;nbsp; R&lt;strong&gt;ealmente no va a cancelar la tarea&lt;/strong&gt;, para eso se requerir&amp;iacute;a un &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx"&gt;CancellationToken&lt;/a&gt;, y no quiero complicar tanto el ejemplo... Aunque tal vez sea buena idea verlo en otro post, m&amp;aacute;s adelante.&lt;/p&gt;
&lt;p align="justify"&gt;El punto de partida ser&amp;aacute; la ventana principal. En mi caso y para no complicarme la vida he creado un formulario muy sencillo con un s&amp;oacute;lo bot&amp;oacute;n, y que contiene un m&amp;eacute;todo que se supone que va a tardar un cierto tiempo en ejecutarse. Iba a poner &amp;lsquo;un huevo&amp;rsquo; pero prefiero no hacerlo para no herir susceptibilidades :-)&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;El formulario principal:&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/MainForm_5F00_38291513.png"&gt;&lt;img height="267" width="366" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/MainForm_5F00_thumb_5F00_6F8F2641.png" alt="MainForm" border="0" title="MainForm" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;El m&amp;eacute;todo que tarda&amp;hellip; mucho:&lt;/strong&gt;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomeHardWork()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 50; i++)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        Console.WriteLine(i);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        Thread.Sleep(100);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }            &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;&lt;strong&gt;El formulario que espera a que la tarea termine:&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreenDesign_5F00_3BE6B9E3.png"&gt;&lt;img height="352" width="451" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreenDesign_5F00_thumb_5F00_0601C4C9.png" alt="WaitForTaskScreenDesign" border="0" title="WaitForTaskScreenDesign" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Una vez dise&amp;ntilde;ada el formulario de espera, le agregaremos algunas propiedades como el t&amp;iacute;tulo, mensaje, y sobre todo el m&amp;eacute;todo que deseamos ejecutar en forma de &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx"&gt;Action&lt;/a&gt;:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Title { get; set; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Message { get; set; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Image Picture { get; set; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Action ActionToExecute { get; set; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Una vez creadas estas propiedades, podemos volver al formulario principal y hacer la llamada a la ventana de espera, pas&amp;aacute;ndole los valores oportunos:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; button1_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (fWaitForTaskScreen fwait = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; fWaitForTaskScreen())&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        fwait.Title = &lt;span style="color:#006080;"&gt;&amp;quot;Executing a looooong task...&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        fwait.Message = &lt;span style="color:#006080;"&gt;&amp;quot;This form will close when the task completes its work.\nJust wait a few seconds... :-)&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        fwait.Picture = Properties.Resources.LogoWeb30_small;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        fwait.ActionToExecute = DoSomeHardWork;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (fwait.ShowDialog() == DialogResult.OK)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            MessageBox.Show(&lt;span style="color:#006080;"&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            MessageBox.Show(&lt;span style="color:#006080;"&gt;&amp;quot;Cancel or error&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }   &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Lo &amp;uacute;nico importante aqu&amp;iacute; es la forma en que le pasamos el m&amp;eacute;todo que debe ejecutar.&amp;nbsp; Estamos usando una propiedad de tipo &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx"&gt;Action&lt;/a&gt;, que representa un m&amp;eacute;todo con un par&amp;aacute;metro que no retorna un valor. De modo, que -ya os aviso- sirve para ejecutar cualquier m&amp;eacute;todo que no devuelva un valor. En caso que queramos devolver un valor podr&amp;iacute;amos utilizar una propiedad p&amp;uacute;blica, o mejor un &lt;a href="http://msdn.microsoft.com/en-us/library/bb549151.aspx"&gt;delegado Func&amp;lt;T, TResult&amp;gt;&lt;/a&gt;. Pero como os dec&amp;iacute;a antes, prefiero no complicar el ejemplo.&lt;/p&gt;
&lt;p align="justify"&gt;El c&amp;oacute;digo es muy sencillo, como pod&amp;eacute;is ver. Crea el formulario de espera, le pasa los valores (incluyendo el m&amp;eacute;todo a ejecutar) y examinamos el valor de DialogResult para saber si ha terminado con &amp;eacute;xito la tarea o no, o se ha cancelado por el usuario.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Y a todo esto &amp;iquest;c&amp;oacute;mo se ejecuta el m&amp;eacute;todo de forma as&amp;iacute;ncrona?&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Pues aqu&amp;iacute; est&amp;aacute; la gracia de este ejercicio. Ya ver&amp;eacute;is lo sencillo que resulta, sobre todo para aquellos acostumbrados a trabajar &amp;lsquo;a pelo&amp;rsquo; con threads:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; fSplashScreen_Shown(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    titleLabel.Text = Title;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    messageLabel.Text = Message;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    pictureBox.Image = Picture;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    Task.Factory.StartNew(ActionToExecute).ContinueWith((t) =&amp;gt; taskCompleted());&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; taskCompleted()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (InvokeRequired)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            Close();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            DialogResult = DialogResult.OK;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }));&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Vayamos por partes. El primer bloque es realmente la parte importante. De hecho, la &amp;uacute;ltima l&amp;iacute;nea es la que se encarga de todo. Crea y ejecuta una tarea as&amp;iacute;ncrona que apunte al m&amp;eacute;todo que le hemos pasado al formulario, y no s&amp;oacute;lo hace eso, si no que adem&amp;aacute;s le decimos que cuando termine ejecute una segunda tarea &amp;lsquo;taskCoompleted&amp;rsquo;. A esto se le llama &lt;a href="http://msdn.microsoft.com/en-us/library/dd537612.aspx"&gt;&amp;lsquo;encadenamiento&amp;rsquo; de tareas,&lt;/a&gt; y es muy &amp;uacute;til cuando una tarea depende de otra.&lt;/p&gt;
&lt;p align="justify"&gt;Y que hace la segunda tarea? Apenas nada. Cierra el formulario y devuelve el valor OK para que la ventana principal sepa que todo ha terminado bien. Lo &amp;uacute;nico que sucede es que -al igual que cuando usamos threads- en .NET no se puede modificar un control fuera del thread que lo ha creado, eso es, el thread principal.&amp;nbsp; Y nuestras tareas se est&amp;aacute;n ejecutando en otros threads creados de forma transparente por la tarea. De modo que para poder llamar al m&amp;eacute;todo Close o modificar la propiedad DialogResult debemos hacerlo mediante &lt;a href="http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx"&gt;Control.Invoke&lt;/a&gt;, y por ese motivo el c&amp;oacute;digo es un poco extra&amp;ntilde;o a primera vista.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreenFinal_5F00_59E4C7D7.png"&gt;&lt;img height="569" width="732" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/WaitForTaskScreenFinal_5F00_thumb_5F00_5E4B22D1.png" alt="WaitForTaskScreenFinal" border="0" title="WaitForTaskScreenFinal" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Os dejo el mini proyecto de ejemplo por si quer&amp;eacute;is jugar un rato:&lt;/p&gt;
&lt;p&gt;&lt;iframe scrolling="no" marginwidth="0" frameborder="0" src="https://skydrive.live.com/embedicon.aspx/MSDN%20Samples/TestWaitForTaskScreen.zip?cid=f3a970280830b5fe&amp;amp;sc=documents" marginheight="0" title="Preview" style="background-color:#fcfcfc;width:98px;height:115px;padding:0px;"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Nos vemos,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200795" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Ejemplo/default.aspx">Ejemplo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Parallel/default.aspx">Parallel</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/MSDN+Forums/default.aspx">MSDN Forums</category></item><item><title>Funciones escalares en TSQL, JOINS, CROSS APPLY, y la madre que parió al topo.</title><link>http://geeks.ms/blogs/lfranco/archive/2011/09/26/funciones-escalares-en-tsql-joins-cross-apply-y-la-madre-que-pari-243-al-topo.aspx</link><pubDate>Mon, 26 Sep 2011 14:52:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200744</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200744</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/09/26/funciones-escalares-en-tsql-joins-cross-apply-y-la-madre-que-pari-243-al-topo.aspx#comments</comments><description>&lt;p align="justify"&gt;Nota: Si eres desarrollador de TSQL puedes saltarte la introducci&amp;oacute;n e ir directamente al tajo ;-)&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/optimization_5F00_30AD39A0.jpg"&gt;&lt;img height="242" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/optimization_5F00_thumb_5F00_2D4BA1F8.jpg" alt="optimization" border="0" title="optimization" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Introducci&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Una de las cosas que m&amp;aacute;s me gustan de SQL server -partiendo de la base de que uno es developer- son las funciones. Existen funciones de dos tipos: Aquellas que devuelven un valor escalar (Scalar-valued) y aquellas que devuelven un valor de tipo tabla (Table-valued), es decir, un conjunto de registros.&lt;/p&gt;
&lt;p align="justify"&gt;Aunque las funciones aparecieron en SQL Server 2000, no fue hasta la aparici&amp;oacute;n de SQL Server 2005 cuando empec&amp;eacute; a usarlas de forma m&amp;aacute;s o menos intensa. A partir de entonces decid&amp;iacute; que casi todo el c&amp;oacute;digo que ten&amp;iacute;a en TSQL en realidad pod&amp;iacute;a estar en funciones, no en procedimientos almacenados como hasta entonces. Y cuando digo casi todo me refiero a que aqu&amp;iacute; hay que diferenciar el c&amp;oacute;digo que principalmente PROCESA datos para devolver un resultado (FUNCIONES), del c&amp;oacute;digo del que meramente realiza ACCIONES (inserts, updates, deletes) sobre los datos (SP).&lt;/p&gt;
&lt;p align="justify"&gt;En mi caso particular, result&amp;oacute; que m&amp;aacute;s de un 85% del c&amp;oacute;digo TSQL era candidato a ser encapsulado en funciones, as&amp;iacute; que con los a&amp;ntilde;os he ido creando una capa de funciones escalares y de tipo tabla para acceder a los datos de varias bases de datos. Y es que desde el punto de vista de un desarrollador resulta muy tentador poder llevar la encapsulaci&amp;oacute;n, uno de nuestros principios favoritos de la orientaci&amp;oacute;n a objetos al mundo de las base de datos: Por ejemplo, crear una funci&amp;oacute;n de tipo tabla en base a unos par&amp;aacute;metros de entrada y poder tratar el resultado como una tabla o vista, haciendo joins, wheres y orders sobre ella es brutal. Y crear una funci&amp;oacute;n escalar que realice una serie de complejas acciones a partir de los par&amp;aacute;metros que recibe y devuelva un resultado que va a ser usado en multitud de ocasiones no tiene precio.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; [dbo].[GetDescriptionScalar](@oId &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;RETURNS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;BEGIN&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @res &lt;span style="color:#0000ff;"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @res= &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt;] + &lt;span style="color:#006080;"&gt;&amp;#39;: &amp;#39;&lt;/span&gt; + [Subject] + &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;CASE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; HasAttachment = 1 &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#006080;"&gt;&amp;#39; (with data)&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;ELSE&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#006080;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;END&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [dbo].[ServerSideGridTest] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; OID = @oId)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;RETURN&lt;/span&gt; @res&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;END&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;&lt;em&gt;Ejemplo de funci&amp;oacute;n escalar: &lt;/em&gt;A partir de un identificador componemos una descripci&amp;oacute;n basada en algunos campos de la tabla.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Rendimiento versus un buen dise&amp;ntilde;o&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Sin embargo, estamos haciendo bien las cosas? En ocasiones no nos damos cuenta de que podemos estar pagando un precio muy alto (rendimiento) a cambio de tener un buen dise&amp;ntilde;o que facilita el mantenimiento. O lo que es peor, a veces damos por asumida una p&amp;eacute;rdida de rendimiento a sabiendas de que ganamos en dise&amp;ntilde;o y reutilizaci&amp;oacute;n de c&amp;oacute;digo. Y esto -en ocasiones- se lleva al extremo con el uso de funciones escalares.&lt;/p&gt;
&lt;p align="justify"&gt;Nadie duda de que la anterior funci&amp;oacute;n es perfectamente v&amp;aacute;lida, y aunque sea muy simple ilustra perfectamente los beneficios de la encapsulaci&amp;oacute;n que permite TSQL. Ahora bien &amp;iquest;que ocurre cuando lanzamos una consulta como esta?&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; t.*, dbo.GetDescriptionScalar(t.oid)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [ServerModeGridProjects].[dbo].[ServerSideGridTest] t&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Supongo que ya os imagin&amp;aacute;is que es una animalada, no? Estamos ejecutando la funci&amp;oacute;n por cada fila de la tabla (en mi caso de ejemplo 100.000 filas), de modo que por muy optimizada que est&amp;eacute; la funci&amp;oacute;n, el rendimiento es bastante penoso, y me recuerda m&amp;aacute;s a un cursor (otro de los demonios particulares de SQL Server) que a otra cosa. Sobre todo si lo comparamos con la misma instrucci&amp;oacute;n en una sola sentencia SQL, ya que el resultado es pr&amp;aacute;cticamente inmediato.&lt;/p&gt;
&lt;p align="justify"&gt;Demos una ojeada al plan de ejecuci&amp;oacute;n:&lt;/p&gt;
&lt;p align="justify"&gt;1) Usando la funci&amp;oacute;n escalar&lt;/p&gt;
&lt;p align="justify"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; t.*, dbo.GetDescriptionScalar(t.oid)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [ServerModeGridProjects].[dbo].[ServerSideGridTest] t&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/eplan_5F00_scalar_5F00_56DF6D2B.png"&gt;&lt;img height="149" width="577" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/eplan_5F00_scalar_5F00_thumb_5F00_1C83F74A.png" alt="eplan_scalar" border="0" title="eplan_scalar" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;2) Usando una sola sentencia SQL&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; t.*, [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt;] + &lt;span style="color:#006080;"&gt;&amp;#39;: &amp;#39;&lt;/span&gt; + [Subject] + &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;CASE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; HasAttachment = 1 &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#006080;"&gt;&amp;#39; (with data)&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;ELSE&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#006080;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;END&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Description]&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [ServerModeGridProjects].[dbo].[ServerSideGridTest] t&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/eplan_5F00_allinone_5F00_492CB123.png"&gt;&lt;img height="110" width="539" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/eplan_5F00_allinone_5F00_thumb_5F00_79DFB8CE.png" alt="eplan_allinone" border="0" title="eplan_allinone" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;A simple vista parecen id&amp;eacute;nticos, sin embargo en el primer caso la consulta tarda &lt;strong&gt;01:04&lt;/strong&gt; (si, &amp;iexcl;m&amp;aacute;s de un minuto!), y en el segundo apenas &lt;strong&gt;tres segundos&lt;/strong&gt;&amp;hellip; WTF?&lt;/p&gt;
&lt;p align="justify"&gt;Vamos a ver que nos dicen las estad&amp;iacute;sticas:&lt;/p&gt;
&lt;p align="justify"&gt;1) Usando la funci&amp;oacute;n escalar&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_scalar_5F00_1196F035.png"&gt;&lt;img height="342" width="670" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_scalar_5F00_thumb_5F00_11F2FD5D.png" alt="stats_scalar" border="0" title="stats_scalar" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;2) Usando una sola sentencia SQL&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_allinone_5F00_3ACDEC99.png"&gt;&lt;img height="340" width="673" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_allinone_5F00_thumb_5F00_71C7CAD2.png" alt="stats_allinone" border="0" title="stats_allinone" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Aqu&amp;iacute; ya podemos observar alguna diferencia no sea con demasiado detalle, sobretodo en las &lt;strong&gt;&lt;span style="color:#ff0000;"&gt;tres &amp;uacute;ltimas filas&lt;/span&gt;&lt;/strong&gt;. Con todo, todav&amp;iacute;a no hemos visto realmente qu&amp;eacute; es lo que sucede DENTRO del servidor cuando lanzamos ambas consultas. Vamos a bajar un poco m&amp;aacute;s a nivel de detalle usando el SQL Profiler. Concretamente nos interesa capturar dos eventos, &lt;strong&gt;SQL:BatchCompleted&lt;/strong&gt; y &lt;strong&gt;SP:Completed&lt;/strong&gt;, adem&amp;aacute;s de algunas columnas c&amp;oacute;mo la &lt;strong&gt;CPU&lt;/strong&gt;, &lt;strong&gt;Duration&lt;/strong&gt; y sobretodo &lt;strong&gt;Reads&lt;/strong&gt; y &lt;strong&gt;Writes&lt;/strong&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;1) Usando la funci&amp;oacute;n escalar&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profilescalar_5F00_4F8FBF4C.png"&gt;&lt;img height="395" width="644" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profilescalar_5F00_thumb_5F00_3E5BE1A9.png" alt="profilescalar" border="0" title="profilescalar" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;M&amp;aacute;s claro agua. Realmente ahora si que estamos viendo c&amp;oacute;mo la funci&amp;oacute;n escalar se ejecuta por cada fila, provocando lo que en ingl&amp;eacute;s se llama RBAR (row-by-agonizing-row). Pero lo m&amp;aacute;s preocupante es el n&amp;uacute;mero total de lecturas y escrituras. Fijaros en la imagen siguiente y podr&amp;eacute;is comprobar que la proporci&amp;oacute;n de lecturas es de 9.603.581 a 2.243. Casi 4.300 veces m&amp;aacute;s! &lt;/p&gt;
&lt;p align="justify"&gt;2) Usando una sola sentencia SQL&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profileallinone_5F00_1CEC1640.png"&gt;&lt;img height="62" width="644" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profileallinone_5F00_thumb_5F00_746D342B.png" alt="profileallinone" border="0" title="profileallinone" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;B&amp;aacute;rbaro! No hay comparaci&amp;oacute;n posible&amp;hellip; Entonces &amp;iquest;cre&amp;eacute;is que en este caso compensa crear una funci&amp;oacute;n escalar? En absoluto. &lt;/p&gt;
&lt;p align="justify"&gt;&amp;iquest;Significa esto que no hay que usar funciones escalares en ning&amp;uacute;n caso? No, pero significa que debemos evaluar con mucho cari&amp;ntilde;o d&amp;oacute;nde hay que usarlas.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;&amp;iquest;Y entonces, d&amp;oacute;nde no hay que usar funciones escalares?&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Sobretodo en valores de columna en un SELECT, como era el caso anterior, pero tampoco en la clausula WHERE ya que tambi&amp;eacute;n provocar&amp;aacute; que se ejecute por cada fila, a fin de evaluar si cumple o no la condici&amp;oacute;n. Tampoco ORDER BY&amp;hellip; Entonces que nos queda? En valores predeterminados de columna? Bueno, tal vez, si no nos vamos a dedicar a realizar INSERTS masivos :-S&lt;/p&gt;
&lt;p align="justify"&gt;Tal vez alguien que sepa m&amp;aacute;s que yo de SQL pueda aclararnos d&amp;oacute;nde usar funciones escalares, pero por el momento voy a descartar su uso. M&amp;aacute;xime cuando existen alternativas :-)&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Funciones de tabla&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Bien, todo esto es muy bonito pero en la vida real &lt;strong&gt;NECESITAMOS USAR FUNCIONES&lt;/strong&gt;. Esta abstracci&amp;oacute;n es primordial en muchos casos, sobre todo cu&amp;aacute;ndo la l&amp;oacute;gica de negocio es compleja. Y que conste que no pretendo iniciar la eterna discusi&amp;oacute;n acerca de si es recomendable o no implementar &amp;eacute;sta en la capa de persistencia de datos o en otra capa de la aplicaci&amp;oacute;n. De hecho, siempre he defendido que contra menos c&amp;oacute;digo exista en la BD mejor :-P&lt;/p&gt;
&lt;p align="justify"&gt;Sin embargo hay ocasiones en las que el aumento de rendimiento no se puede obviar. En un proyecto en el que estoy trabajando actualmente, hay tal cantidad de datos y se realizar unos procesos tan bestias que uno de los algoritmos de c&amp;aacute;lculo -optimizado- tardaba cerca de un minuto. Moviendo esta algoritmo de la aplicaci&amp;oacute;n a una serie de funciones hemos conseguido que sea casi instant&amp;aacute;neo.&lt;/p&gt;
&lt;p align="justify"&gt;Vale, y c&amp;oacute;mo hemos hecho esto? Usando funciones de tabla. &lt;/p&gt;
&lt;p align="justify"&gt;Existen dos tipos de funciones de tabla, pero ahora las trataremos por un igual, ya que en ambos casos lo que se devuelve ese un conjunto de filas y columnas. De este modo ser&amp;iacute;a perfectamente transformar la anterior funci&amp;oacute;n escalar en esto:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FUNCTION&lt;/span&gt; [dbo].[GetDescriptionTable](@oId &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;RETURNS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;RETURN&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt;] + &lt;span style="color:#006080;"&gt;&amp;#39;: &amp;#39;&lt;/span&gt; + [Subject] + &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;CASE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; HasAttachment = 1 &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#006080;"&gt;&amp;#39; (with data)&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;ELSE&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#006080;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;END&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Description&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    [dbo].[ServerSideGridTest] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    OID = @oId&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Observar que aunque se trata de una funci&amp;oacute;n de tipo tabla en realidad estamos devolviendo un s&amp;oacute;lo campo y un s&amp;oacute;lo registro. En cualquier caso esto no es para nada importante, y de hecho la verdadera potencia del uso de funciones de tipo tabla radica en devolver conjuntos de registros, y c&amp;oacute;mo no, realizar sobre &amp;eacute;stos operaciones de tipo JOIN, WHERE, etc.&lt;/p&gt;
&lt;p align="justify"&gt;&amp;iquest;No ser&amp;iacute;a genial poder hacer un JOIN de una tabla con el retorno de una funci&amp;oacute;n de tipo tabla? Pues es posible hacerlo&amp;hellip; salvo en el caso que la funci&amp;oacute;n espere un par&amp;aacute;metro que referencie la fila. Por ejemplo, el siguiente c&amp;oacute;digo no es v&amp;aacute;lido (supongamos que la funci&amp;oacute;n anterior de tipo tabla tambi&amp;eacute;n devuelve el Id):&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    t.*, dt.[Description] &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Description]&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    [ServerModeGridProjects].[dbo].[ServerSideGridTest] t&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;INNER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; GetDescriptionTable(&lt;span style="color:#ff0000;"&gt;t.oid&lt;/span&gt;) dt&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; t.OId = dt.OId&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Se producir&amp;aacute; un error, ya que SQL Server no es capaz de resolver GetDescriptionTable(&lt;span style="color:#ff0000;"&gt;t.oid&lt;/span&gt;). &lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;CROSS APPLY al rescate!&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Aqu&amp;iacute; entra este operador (bueno, en realidad son dos) que permite combinar los valores del lado izquierdo con los del lado derecho, creando el conjunto de resultados deseado. Utilizarlo es tan sencillo como esto:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; t.*, dt.[Description] &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Description]&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [ServerModeGridProjects].[dbo].[ServerSideGridTest] t&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; APPLY GetDescriptionTable(t.oid) dt&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Sencillo y hermoso. Pero, que tal anda de rendimiento?&lt;/p&gt;
&lt;p align="justify"&gt;Pues muy bien, la verdad. Tarda exactamente &lt;strong&gt;tres segundos&lt;/strong&gt;. Lo mismo que el caso anterior en el que ten&amp;iacute;amos una sola sentencia SQL. Es m&amp;aacute;s, si mostramos las estad&amp;iacute;sticas vemos que se comporta de forma muy parecida:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_crossapply_5F00_0590EC02.png"&gt;&lt;img height="332" width="644" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/stats_5F00_crossapply_5F00_thumb_5F00_5B613E19.png" alt="stats_crossapply" border="0" title="stats_crossapply" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profilecrossapply_5F00_73084FB2.png"&gt;&lt;img height="61" width="644" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/profilecrossapply_5F00_thumb_5F00_70EB50E9.png" alt="profilecrossapply" border="0" title="profilecrossapply" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Se puede apreciar un ligero aumento de las lecturas, pero en realidad no es nada significativo en t&amp;eacute;rminos de rendimiento, ya que la duraci&amp;oacute;n es exactamente la misma.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusi&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Las funciones escalares pueden suponer un problema serio de performance. Sobre todo cuando no se tiene en mente c&amp;oacute;mo funcionan. Una alternativa a tener en cuenta es utilizar funciones de tipo tabla en combinaci&amp;oacute;n con CROSS APPLY, ya que proporcionan un buen dise&amp;ntilde;o a la vez el rendimiento no se ve penalizado en absoluto.&lt;/p&gt;
&lt;p align="justify"&gt;BTW creo que voy a tener que replantearme esto de escribir&amp;hellip; cada vez me salen posts m&amp;aacute;s &amp;lsquo;tochos&amp;rsquo;. &lt;/p&gt;
&lt;p align="justify"&gt;Enhorabuena si has llegado hasta aqu&amp;iacute; ;-)&lt;/p&gt;
&lt;p align="justify"&gt;Nos leemos,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200744" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/TSQL/default.aspx">TSQL</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Optimizaci_26002300_243_3B00_n/default.aspx">Optimizaci&amp;#243;n</category></item><item><title>Usando SQL Server Table-Valued Parameters en C# (mediante un Custom Iterator)</title><link>http://geeks.ms/blogs/lfranco/archive/2011/09/12/usando-sql-server-table-valued-parameters-en-c-mediante-un-custom-iterator.aspx</link><pubDate>Mon, 12 Sep 2011 14:42:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200445</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=200445</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/09/12/usando-sql-server-table-valued-parameters-en-c-mediante-un-custom-iterator.aspx#comments</comments><description>&lt;p align="justify"&gt;Una de las caracter&amp;iacute;sticas m&amp;aacute;s esperadas de SQL Server 2008 son los par&amp;aacute;metros de tipo tabla en procedimientos almacenados y funciones de SQL SERVER. &lt;/p&gt;
&lt;p align="justify"&gt;Estos &lt;a href="http://msdn.microsoft.com/en-us/library/bb675163.aspx"&gt;Table-Valued Parameter&lt;/a&gt; (TVP en adelante ) permiten definir un tipo de datos estructurado (al fin!) que puede ser pasado como par&amp;aacute;metro a un PROCEDURE o a una FUNCTION, mejorando sustancialmente el manejo de datos de tipo tabla, ya que anteriormente depend&amp;iacute;amos de tablas temporales o variables de tipo tabla, pero ambas ten&amp;iacute;an varios inconvenientes. Las primeras por ejemplo s&amp;oacute;lo eran accesibles en la conexi&amp;oacute;n actual, mientras que las segundas ni siquiera pod&amp;iacute;an ser accedidas desde otros elementos procedimientos o funciones.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;SQL Server 2008 y TVP al rescate!&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Mediante los TVP podemos definir un tipo fuertemente tipado en el servidor (valga la rebuznancia :-P), y usarlo para definir los par&amp;aacute;metros de nuestros procedimientos o funciones. De este modo estamos portando una de las cosas que m&amp;aacute;s me gustan de la OOP a TSQL, que dicho sea de paso, falta le hac&amp;iacute;a. Adem&amp;aacute;s, nos permite solventar algo que desde tiempo ha llevado de cabeza a muchos desarrolladores: El poder enviar en un s&amp;oacute;lo viaje al servidor varias filas. &lt;/p&gt;
&lt;p align="justify"&gt;Vamos a ver. Que levante la mano qui&amp;eacute;n no se ha dado cabezazos para tratar de mandar varios valores a un procedimiento o funci&amp;oacute;n desde una aplicaci&amp;oacute;n cliente?&lt;/p&gt;
&lt;p align="justify"&gt;A lo largo de los a&amp;ntilde;os he visto soluciones m&amp;aacute;s o menos ingeniosas, desde pasar un &amp;lsquo;chorizo&amp;rsquo; de 4000 caracteres separados por comas y usarlo con SQL din&amp;aacute;mico o volcarlo en una tabla temporal para hacer un JOIN, hasta &lt;a href="http://geeks.ms/blogs/lfranco/archive/2008/03/12/t-sql-leer-par-225-metros-xml-y-convertirlos-en-tablas.aspx"&gt;usar XML para el paso de valores&lt;/a&gt;, pasando por tablas temporales globales y otras &amp;lsquo;perlas&amp;rsquo;. En todos los casos las soluciones distaban mucho de ser perfectas y comportaban serios problemas de rendimiento al tener que implementar l&amp;oacute;gica en ambos extremos para empaquetar y desempaquetar los valores.&lt;/p&gt;
&lt;p align="justify"&gt;Aqu&amp;iacute; los TVP nos vienen a echar un cable, ya que permiten definir un tipo de registro que luego pasaremos a SQL Server, aunque la gracias de todo est&amp;aacute; en -como veremos un poco m&amp;aacute;s adelante- crearse un &lt;a href="http://msdn.microsoft.com/en-us/library/dscyy5s0.aspx"&gt;custom iterator&lt;/a&gt; en c#.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;Manos a la obra: Coding&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Un escenario t&amp;iacute;pico (y que vamos a usar como ejemplo) es el de tener una aplicaci&amp;oacute;n cliente que permite seleccionar un subconjunto de datos, por ejemplo bancos. Y posteriormente, env&amp;iacute;a &amp;eacute;sta selecci&amp;oacute;n de elementos a un procedimiento o funci&amp;oacute;n que realice *algo* con &amp;eacute;stos datos, como por ejemplo mostrar un listado por pantalla, report, etc.&lt;/p&gt;
&lt;p align="justify"&gt;La parte del servidor es la m&amp;aacute;s sencilla, supongamos que partimos de un par de tablas de bancos y oficinas:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/banksoffices_5F00_2B31A129.png"&gt;&lt;img height="225" width="527" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/banksoffices_5F00_thumb_5F00_088D62AE.png" alt="banksoffices" border="0" title="banksoffices" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Basta con crear un tipo de datos de tipo tabla (con un s&amp;oacute;lo campo para simplificar):&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; TYPE [dbo].[MultiSelectionList] &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt;(&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    [Id] [&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;] &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A continuaci&amp;oacute;n usamos este tipo en las funciones o procedimientos almacenados para recibir los valores como una tabla de elementos de este tipo :&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FUNCTION&lt;/span&gt; [dbo].[GetBanksOffices](@SELECTION &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; MultiSelectionList READONLY)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;RETURNS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;RETURN&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; [system].[BankOffices] BO&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;INNER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; @SELECTION S&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; BO.BankId = S.Id&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Observar el uso de READONLY, ya que es imperativo que la lista de valores no se pueda modificar desde el cuerpo de la rutina TSQL. Por otro lado, la lista de valores se trata a todos los efectos como una tabla temporal, o variable de tipo tabla. As&amp;iacute; pues podemos realizar un JOIN sobre ella sin m&amp;aacute;s, y aqu&amp;iacute; radica la belleza de los TVP, nos permiten un c&amp;oacute;digo mucho m&amp;aacute;s limpio. Y como todos sabemos, contra m&amp;aacute;s limpio es un c&amp;oacute;digo, menos propenso a errores resulta.&lt;/p&gt;
&lt;p align="justify"&gt;La parte del cliente es un poco m&amp;aacute;s compleja, ya que supongo que la mayor&amp;iacute;a os estar&amp;eacute;is preguntando &amp;ldquo;vale &amp;iquest;pero c&amp;oacute;mo demonios se le pasa un par&amp;aacute;metro de este tipo desde .NET?&amp;rdquo;, y con raz&amp;oacute;n. Este tipo es un tipo de datos personalizado que *s&amp;oacute;lo* conoce nuestro servidor. Sin embargo en .NET podemos crearnos el equivalente a este tipo mediante una clase, y luego mediante una lista gen&amp;eacute;rica pas&amp;aacute;rselo a la funci&amp;oacute;n mediante un SqlParameter&amp;hellip; o lo ser&amp;iacute;a si existiese un tipo de par&amp;aacute;metro adaptado a las colecciones gen&amp;eacute;ricas, cosa que no es as&amp;iacute;.&lt;/p&gt;
&lt;p align="justify"&gt;Entonces que hacemos? Pues lo primero empezar por lo b&amp;aacute;sico: Hay que crear una clase equivalente al tipo de datos de SQL SERVER:&lt;/p&gt;
&lt;div&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; MultiSelectionItem&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Id { get; set; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MultiSelectionItem(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        Id = id;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Ya tenemos lo b&amp;aacute;sico para empezar. Ahora a ver c&amp;oacute;mo podemos conectar nuestros objetos de negocio con los TVP de SQL SERVER:&lt;/p&gt;
&lt;p align="justify"&gt;El mecanismo que nos proporciona ADO.NET para acceder a procedimientos o funciones son los archiconocidos SqlCommand y SqlParameter, los cuales he usado infinidad de veces. Sin embargo, hasta hoy no conoc&amp;iacute;a la existencia de uno de los valores de la enumeraci&amp;oacute;n SqlDbType: El valor Structured. Cuando usamos este valor para definir el tipo del par&amp;aacute;metro de SQL Server, en realidad estamos especificando que vamos a usar un TVP. Esto parece solventar parte del problema, ahora s&amp;oacute;lo nos falta ver como convertir una colecci&amp;oacute;n de objetos MultiSelectionItem y &amp;lsquo;convertirla&amp;rsquo; a un objeto que podamos pasarle al par&amp;aacute;metro.&lt;/p&gt;
&lt;p align="justify"&gt;Ahora demos un vistazo a la clase &lt;a href="http://msdn.microsoft.com/en-us/library/ms131105.aspx"&gt;SqlDataRecord&lt;/a&gt;, que representa una fila de datos junto con sus metadatos, y est&amp;aacute; especialmente indicada para su uso en conjunci&amp;oacute;n con SqlCommand y SqlDataReader, para enviar y recibir informaci&amp;oacute;n de procedimientos y funciones utilicen TVP.&lt;/p&gt;
&lt;p align="justify"&gt;Es muy posible que est&amp;eacute;is pensando en usar esta clase como &amp;lsquo;puente&amp;rsquo; entre ambos mundos, y la verdad es que SI SE PUEDE. Y adem&amp;aacute;s, creo que de forma muy elegante.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom iterators en C#&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Un iterador es un m&amp;eacute;todo que realiza una iteraci&amp;oacute;n personalizada sobre una colecci&amp;oacute;n a trav&amp;eacute;s de la palabra reservada &lt;a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx"&gt;yield&lt;/a&gt;. La instrucci&amp;oacute;n yield return provoca que un elemento en la secuencia de origen sea devuelto de inmediato al m&amp;eacute;todo llamador que llama antes de que el siguiente elemento de la secuencia de origen sea procesado. En otras palabras, nos permite hacer algo tan bonito como esto:&lt;/p&gt;
&lt;div&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; MultiSelectionCollection : List&amp;lt;MultiSelectionItem&amp;gt;, IEnumerable&amp;lt;SqlDataRecord&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    IEnumerator&amp;lt;SqlDataRecord&amp;gt; IEnumerable&amp;lt;SqlDataRecord&amp;gt;.GetEnumerator()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        var sqlDataRecord = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlDataRecord(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlMetaData(&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, SqlDbType.Int));&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (MultiSelectionItem multiSelectionItem &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            sqlDataRecord.SetInt32(0, multiSelectionItem.Id);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;yield&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; sqlDataRecord;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;De verdad que a veces no me imagino la vida antes de la aparici&amp;oacute;n de Generics :-P&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Poni&amp;eacute;ndolo todo junto&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Recapitulemos. Por un lado tenemos el TVP que hemos creado en SQL SERVER, y que posteriormente hemos usado en una funci&amp;oacute;n de usuario de tipo tabla. A continuaci&amp;oacute;n hemos creado una clase equivalente en la aplicaci&amp;oacute;n cliente, y finalmente hemos creado una clase que hereda de una lista gen&amp;eacute;rica de nuestro tipo equivalente, y que implementa la interfaz IEnumerable, para as&amp;iacute; poder crear un iterador personalizado que &amp;lsquo;convierta&amp;rsquo; la lista de elementos MultiSelectionItem en algo inteligible para SQL Server, en este caso una secuencia de elementos SqlDataRecord.&lt;/p&gt;
&lt;p&gt;Y ahora que? Ahora, s&amp;oacute;lo queda hacer la llamada a la funci&amp;oacute;n. Es decir, crear la colecci&amp;oacute;n de valores a pasar a SQL SERVER, hacer la llamada y recoger los datos de vuelta:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; List&amp;lt;BankOffice&amp;gt; GetBanksOffices(MultiSelectionCollection selectedbanks)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    var officebanks = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;BankOffice&amp;gt;();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (SqlConnection sqlcon = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnection(&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        ConnectionStringManager.GetFirstConnectionString()))&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            sqlcon.Open();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; sql = &lt;span style="color:#006080;"&gt;&amp;quot;SELECT * FROM dbo.GetBanksOffices(@SELECTION)&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (SqlCommand sqlcmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlCommand(sql, sqlcon))&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                SqlParameter param = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="color:#006080;"&gt;&amp;quot;@SELECTION&amp;quot;&lt;/span&gt;, SqlDbType.Structured);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                param.TypeName = &lt;span style="color:#006080;"&gt;&amp;quot;MultiSelectionList&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                param.Value = selectedbanks;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                sqlcmd.Parameters.Add(param);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                var result = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (result.Read())&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                    BankOffice newoffice = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; BankOffice&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                        BankOfficeId = &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.Parse(result[0].ToString()),&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                        ShowOrder = &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.Parse(result[1].ToString()),&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                        BankId = &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.Parse(result[2].ToString()),&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                        OfficeId = &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;.Parse(result[3].ToString()),&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                        Name = result[4].ToString()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                    };&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                    officebanks.Add(newoffice);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;                }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; officebanks;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;Un par de cosas importantes: Aunque parece que estamos haciendo lo de siempre, fijaros en que el tipo de datos del par&amp;aacute;metro de SQL SERVER es SqlDbType.Structured, y adem&amp;aacute;s hay que indicar el nombre del tipo de datos de SQL SERVER mediante la propiedad TypeName. Esto es m&amp;aacute;s importante de lo que parece, ya que el nombre del tipo de datos de SQL SERVER no tiene por que coincidir con el nombre que hemos dado a nuestra clase en la aplicaci&amp;oacute;n cliente.&lt;/p&gt;
&lt;p&gt;Y para probar la llamada, basta con crear una colecci&amp;oacute;n con los valores que deseamos pasar a la funci&amp;oacute;n:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;var selectedbanks = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MultiSelectionCollection();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;selectedbanks.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MultiSelectionItem(1));&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;selectedbanks.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MultiSelectionItem(3));&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;var result = TVPExtensions.GetBanksOffices(selectedbanks);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;result.ForEach(p =&amp;gt; Console.WriteLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;{0}, {1}&amp;quot;&lt;/span&gt;, p.BankId, p.Name)));&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Y tach&amp;aacute;n!!! Ya hemos visto c&amp;oacute;mo pasar listas de valores a procedimientos y funciones de SQL mediante TVP.&lt;/p&gt;
&lt;p&gt;Nos leemos ;-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200445" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Generics/default.aspx">Generics</category></item><item><title>Editar documentos almacenados como array de bits en SQL Server [FileStream] (3/n)</title><link>http://geeks.ms/blogs/lfranco/archive/2011/08/19/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-3-n.aspx</link><pubDate>Fri, 19 Aug 2011 10:52:32 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:199707</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=199707</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/08/19/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-3-n.aspx#comments</comments><description>&lt;p align="justify"&gt;Es viernes, así que intentaré terminar la serie. Espero que no me quede un post muy ‘tocho’ :-P&lt;/p&gt;  &lt;p align="justify"&gt;Después de abrir boca con los dos posts anteriores, en los que hemos mostrado cómo &lt;a href="http://geeks.ms/blogs/lfranco/archive/2011/08/17/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-1-n.aspx"&gt;crear una tabla con almacenamiento FILESTREAM&lt;/a&gt;, y posrteriormente &lt;a href="http://geeks.ms/blogs/lfranco/archive/2011/08/18/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-2-n.aspx"&gt;cómo almacenar en ella documentos en forma de información binaria&lt;/a&gt;, hoy vamos a terminar la serie viendo cómo poder visualizar esta información mediante su aplicación asociada (Word, Excel, Acrobar Reader, etc.) y cómo no, editarla para guardar los cambios otra vez en la base de datos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsword_5F00_7E1E6DD8.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="fsword" border="0" alt="fsword" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsword_5F00_thumb_5F00_12E0408C.png" width="891" height="504" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;Mis disculpas :-)&lt;/strong&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Antes de continuar os quiero decir que mi intención original era encontrar una solución más elegante, pero como no he sido capaz de encontrarla (y por lo que he visto en Internet, no he sido el único) os dejo una solución que no es tan elegante, pero al menos funciona.&lt;/p&gt;  &lt;p align="justify"&gt;Que cual era mi intención original? Pues me hubiese gustado poder abrir directamente la información binaria en -por ejemplo- Word. Creía que lo podría conseguir obteniendo un handle y pasándoselo a la aplicación asociada… pero los handles obtenidos mediante &lt;a href="http://msdn.microsoft.com/en-us/library/bb933972.aspx"&gt;OpenSqlFilestream&lt;/a&gt; son locales al proceso :-(&lt;/p&gt;  &lt;p align="justify"&gt;Dicho de otro modo, podemos acceder al fichero, leerlo, editarlo, pero sólo si lo hace nuestra aplicación. Si el fichero debe ser controlado a través de otra aplicación no podemos pasarle el handle. Así que esta opción no sirve.&lt;/p&gt;  &lt;p align="justify"&gt;Otra opción que contemplé (inspirado en mi querido y odiado SharePoint) fue crear un manejador HTTP con ASP.NET, ya que algunas aplicaciones son capaces de trabajar con documentos abiertos a través de una URL. Sin embargo, sólo conseguí hacerlo funcionar con documentos de Office (y no en el 100% de los casos).&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;La solución. Mi solución (seguro que hay más)&lt;/strong&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Así pues tuve que recurrir a la opción que pretendía evitar a toda costa, que no es otra que: Leer la información binaria, crear un fichero temporal en la estación cliente y abrirlo con la aplicación asociada. Que tiene de malo esta solución? Pues que para visualizar documentos funciona muy bien, pero en realidad estamos mostrando –y editando- una copia del documento, de modo que para revertir los cambios que hace el usuario a la base de datos tenemos un problema. Un problemón.&lt;/p&gt;  &lt;p align="justify"&gt;Después de darle algunas vueltas y comentarlo con más gente (gracias Pablo Gavela!) al final me decanté por utilizar la clase Process. Si, la misma clase process que hemos usado miles de veces para ejecutar aplicaciones o mostrar documentos. La clase process puede lanzar un proceso de forma síncrona o asíncrona. &lt;/p&gt;  &lt;p align="justify"&gt;La primera la deseché en seguida porque creo que usa algo que los viejos programadores del API de Win32 aprendimos a temer: WaitForExit (que llama a WaitForSingleObject). Además, la aplicación deja de responder hasta que se termina el proceso lanzado, con lo que ni siquiera repinta la ventana.&lt;/p&gt;  &lt;p align="justify"&gt;La segunda permite lanzar un proceso y monitorizar el momento en que se cierra mediante el evento ‘Exited’. De modo que podemos saber el momento en que se cierra la aplicación asociada, verificar si se ha cambiado el documento y en caso afirmativo volver a guardarlo en la base de datos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;em&gt;Nota importante: Si queremos que se dispare el evento ‘Exited’ hay que activar la propiedad ‘EnableRaisingEvents’.&lt;/em&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Un poco rocambolesco? Tal vez. Así que si alguien encuentra una solución más sencilla que lo haga público. Por favor :-)&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;Al fin! El maldito código&lt;/strong&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Mi propuesta es crear una clase derivada de Process con la información adicional que necesitamos para el manejo de los datos binarios. En este caso particular necesito que el proceso ‘conozca’ el identificador del registro (FileId Guid), el nombre original del documento (o al menos su extensión), y evidentemente los propios datos binarios.&lt;/p&gt;  &lt;p align="justify"&gt;La idea es pasarle estos datos ‘extra’ en el constructor, y posteriormente llamar a un método que se encargue de crear el fichero temporal y obtener la fecha de la última escritura. Posteriormente ‘escucharemos’ el evento ‘Exited’ y cuando se dispare verificaremos si hay cambios (comparando la fecha de última escritura con la anterior) y si los hay, guardaremos los cambios en la base de datos a través del FileId que hemos pasado enteriormente al proceso.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;La clase ProcessController&lt;/strong&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ProcessController : Process&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    DateTime originalLastWriteTime;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Byte[] document = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; tempfileName = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; TempFileName&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        get&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; tempfileName;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Guid fileId;        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Guid FileId&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        get&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; fileId;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ProcessController(Byte[] documentBytes, Guid docId, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; originalfilename)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        : &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        tempfileName = Path.GetTempFileName().Replace(&lt;span style="color:#006080;"&gt;&amp;quot;tmp&amp;quot;&lt;/span&gt;, getExtension(originalfilename));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        document = documentBytes;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        fileId = docId;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.StartInfo.FileName = tempfileName;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; EditInAssociatedApplication()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (tempfileName == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (File.Exists(tempfileName)) File.Delete(tempfileName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        File.WriteAllBytes(tempfileName, document);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        originalLastWriteTime = File.GetLastWriteTime(tempfileName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.EnableRaisingEvents = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Start();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; HasChanged()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (tempfileName == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        var modifiedtime = File.GetLastWriteTime(tempfileName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (modifiedtime != originalLastWriteTime);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; getExtension(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; filename)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        var parts = filename.Split(&lt;span style="color:#006080;"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (parts.Length &amp;gt; 0)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; parts[parts.Length - 1];&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Para usar esta clase en nuestra aplicación lo mejor es tener una lista con los procesos que vamos abriendo, y por cada uno de ellos escuchar su evento ‘Exited’. De este modo cada vez que abrimos un proceso nuevo lo agregamos a la lista, y cada vez que se cierra un proceso, comprobamos si hay cambios y lo volcamos a la base de datos. Un ejemplo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;List&amp;lt;ProcessController&amp;gt; Processes = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;ProcessController&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; editDocument(Guid docId)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var filestreamDoc = context.FileStreamDocuments.FirstOrDefault(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        p =&amp;gt; p.FileId == docId);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (filestreamDoc == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ProcessController process = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ProcessController(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        filestreamDoc.Document.ToArray(),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        filestreamDoc.FileId, filestreamDoc.OriginalPath);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    process.Exited += process_Exited;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    process.EditInAssociatedApplication();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Processes.Add(process);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; process_Exited(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ProcessController process = sender &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; ProcessController;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (process == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (process.HasChanged())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        saveDocument(process.FileId, process.TempFileName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; saveDocument(Guid docId, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; filename)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var filestreamDoc = context.FileStreamDocuments.FirstOrDefault(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        p =&amp;gt; p.FileId == docId);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (filestreamDoc == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (File.Exists(filename))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        filestreamDoc.Document = File.ReadAllBytes(filename);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        context.SubmitChanges();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;No quiero alargar más el post, así que os dejo algo como ejercicio por si alguien se anima: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cada vez que se cierra un proceso deberíamos eliminarlo de la lista.&lt;/li&gt;

  &lt;li&gt;Si el usuario cierra la aplicación y existen procesos abiertos, deberíamos avisarlo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ala, ya doy por acabada la serie. Y justo a tiempo. Nos leemos :-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=199707" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category></item><item><title>Editar documentos almacenados como array de bits en SQL Server [FileStream] (2/n)</title><link>http://geeks.ms/blogs/lfranco/archive/2011/08/18/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-2-n.aspx</link><pubDate>Thu, 18 Aug 2011 11:41:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:199652</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=199652</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/08/18/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-2-n.aspx#comments</comments><description>&lt;p align="justify"&gt;En el &lt;a href="http://geeks.ms/blogs/lfranco/archive/2011/08/17/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-1-n.aspx"&gt;anterior post&lt;/a&gt; de la serie os comentaba: &amp;ldquo;En los pr&amp;oacute;ximos posts veremos d&amp;oacute;nde se almacenan REALMENTE estos ficheros, c&amp;oacute;mo visualizarlos, y lo m&amp;aacute;s importante de todo, c&amp;oacute;mo editarlos y guardarlos otra vez en la base de datos de forma transparente para el usuario.&amp;rdquo;&lt;/p&gt;
&lt;p align="justify"&gt;Dicho y hecho. Vamos a dar una ojeada al servidor SQL para ver &lt;strong&gt;d&amp;oacute;nde&lt;/strong&gt; se almacenan estos ficheros. Recordar que al crear la base de datos debemos especificar un FILEGROUP expl&amp;iacute;citamente para el almacenamiento FILESTREAM:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DATABASE&lt;/span&gt; Archive &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; ( NAME = Arch1,&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    FILENAME = &lt;span style="color:#006080;"&gt;&amp;#39;c:\data\archdat1.mdf&amp;#39;&lt;/span&gt;),&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;FILEGROUP FileStreamGroup1 &lt;span style="color:#0000ff;"&gt;CONTAINS&lt;/span&gt; FILESTREAM( NAME = Arch3,&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    FILENAME = &lt;span style="color:#006080;"&gt;&amp;#39;c:\data\filestream1&amp;#39;&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;LOG &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;  ( NAME = Archlog1,&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    FILENAME = &lt;span style="color:#006080;"&gt;&amp;#39;c:\data\archlog1.ldf&amp;#39;&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;El ejemplo anterior crea una estructura de carpetas y ficheros en la ubicaci&amp;oacute;n especificada del servidor SQL. Observar que no tiene porque ser la misma que los ficheros MDF y LDF, es m&amp;aacute;s, para escenarios de alto rendimiento no os lo aconsejo precisamente.&lt;/p&gt;
&lt;p align="justify"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;Si damos una vistazo a esa estructura veremos que por defecto se crea un fichero &lt;strong&gt;filestream.hdr&lt;/strong&gt; y una carpeta &lt;strong&gt;$FSLOG&lt;/strong&gt;. El primero contiene los metadatos para el contenedor de los datos y el seguindo es el equivalente del log de transacciones de una base de datos. Pura &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163388.aspx"&gt;magia&lt;/a&gt;!&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsfolders_5F00_1AD418A9.png"&gt;&lt;img height="101" width="397" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsfolders_5F00_thumb_5F00_756A253A.png" alt="fsfolders" border="0" title="fsfolders" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;En nuestro caso, aparece adem&amp;aacute;s una carpeta por cada entidad o tabla que contiene campos binarios con almacenamiento FILESTREAM. Como me he decicado a insertar varios documentos de pruebas en la tabla que creamos previamente (unos 1.500 para probar), la carpeta contiene una lista de ficheros similar a esto:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsfiles_5F00_5476B293.png"&gt;&lt;img height="338" width="397" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/fsfiles_5F00_thumb_5F00_77577443.png" alt="fsfiles" border="0" title="fsfiles" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Estos ficheros no tienen extensi&amp;oacute;n ni ning&amp;uacute;n tipo de v&amp;iacute;nculo con el documento original. Por eso es importante guardar en la tabla algunos de los metadatos del fichero original, ya que si no es imposible saber que tipo de documento es, ni como visualizarlo (ni mucho menos editarlo). Tambi&amp;eacute;n es importante resaltar que estos ficheros no pueden ser accedidos directamente a trav&amp;eacute;s de la red local. A todos los efectos los datos es como si estuviesen f&amp;iacute;sicamente dentro de la tabla, en el fichero MDF.&lt;/p&gt;
&lt;p align="justify"&gt;Las grandes ventajas de este enfoque respecto a la alternativa &amp;lsquo;cl&amp;aacute;sica&amp;rsquo; de almacenar s&amp;oacute;lo la ruta de acceso a los documentos, y tener &amp;eacute;stos en una ubicaci&amp;oacute;n de red son a mi juicio: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;Atomicidad&lt;/strong&gt;: Al fin tenemos un mecanismo que asegura que un registro y un fichero NTFS van a comportarse como una sola entidad, garantizando plenamente su integridad, olvid&amp;aacute;ndonos de mecanismos de sincronizaci&amp;oacute;n (con todo lo que conlleva).&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;Seguridad&lt;/strong&gt;: La seguridad se gestiona desde SQL Server, con los usuarios y roles de SQL Server (independientemente de si usamos seguridad integrada o de SQL Server). Podemos olvidarnos de crear listas ACL separadas para controla los accesos a los ficheros NTFS.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;Backups&lt;/strong&gt;: Esto no se paga con dinero. Adios a tener que programar copias separadas de la base de datos y de los ficheros. Ahora al realizar un backup, SQL Server copiar&amp;agrave; de forma autom&amp;aacute;tica la estructura de carpetas (y la restaurar&amp;aacute;, que es lo m&amp;aacute;s importante).&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Pero no todo son ventajas, os recomiendo dar una ojeada a la Tabla 1 de &lt;a href="http://msdn.microsoft.com/en-us/library/cc949109(v=sql.100).aspx"&gt;este art&amp;iacute;culo&lt;/a&gt;, que nos ofrece una comparativa muy detallada entre los 3 modelos (Filesystem, varbinary(max) y FILESTREAM).&lt;/p&gt;
&lt;p align="justify"&gt;Por ejemplo, una de las cosas que es muy sencillo hacer es la visualizaci&amp;oacute;n y edici&amp;oacute;n de los documentos, cuando &amp;eacute;stos est&amp;aacute;n almacenados en una ubicaci&amp;oacute;n de red&amp;nbsp; accesible por los usuarios de la aplicaci&amp;oacute;n. Si sabemos la ruta de acceso al fichero basta hacer un Process.Start y &amp;eacute;ste se abrir&amp;aacute; con la aplicaci&amp;oacute;n asociada:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; editDocument(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; filename)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    Process.Start(filename);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sin embargo utilizando almacenamiento FILESTREAM esto no es tan evidente&amp;hellip; Pero eso lo dejo para el siguiente post. &lt;/p&gt;
&lt;p&gt;Nos leemos pronto! :-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=199652" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category></item><item><title>Editar documentos almacenados como array de bits en SQL Server [FileStream] (1/n)</title><link>http://geeks.ms/blogs/lfranco/archive/2011/08/17/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-1-n.aspx</link><pubDate>Wed, 17 Aug 2011 16:25:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:199583</guid><dc:creator>Lluis Franco</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lfranco/rsscomments.aspx?PostID=199583</wfw:commentRss><comments>http://geeks.ms/blogs/lfranco/archive/2011/08/17/editar-documentos-almacenados-como-array-de-bits-en-sql-server-filestream-1-n.aspx#comments</comments><description>&lt;p align="justify"&gt;Bajo este t&amp;iacute;tulo -a priori tan chorra-, voy a empezar una serie de posts que muestren c&amp;oacute;mo almacenar documentos (ficheros NTFS) en una base de datos SQL Server 2008 mediante el uso de FILESTREAM storage, y c&amp;oacute;mo visualizarlos y editarlos con su aplicaci&amp;oacute;n asociada. En realidad, &amp;eacute;sta &amp;uacute;ltima parte &amp;ndash;la edici&amp;oacute;n- es la &amp;uacute;nica compleja, pero me ha parecido un buen tema para empezar una serie, y as&amp;iacute; de paso retomar las viejas costumbres.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;strong&gt;FILESTREAM Storage:&lt;/strong&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Una de las caracter&amp;iacute;sticas m&amp;aacute;s esperadas de SQL Server 2008 &amp;ndash;al menos por mi parte- es el &lt;a href="http://msdn.microsoft.com/en-us/library/cc949109(v=sql.100).aspx"&gt;almacenamiento en FILESTREAM&lt;/a&gt; de grandes ficheros como array de bytes, en campos de tipo varbinary(MAX) dentro de nuestra base de datos. El punto fuerte de este tipo de almacenamiento es que en lugar de almacenar el array de bytes dentro de la tabla lo almacena de forma transparente en el sistema de ficheros NTFS, pero con todas las ventajas de SQL Server (Atomicidad, facilidad para realizar backups, rendimiento, seguridad, etc.). Esto permite adem&amp;aacute;s que el tama&amp;ntilde;o de la BD no crezca despesuradamente, ya que la edici&amp;oacute;n express *s&amp;oacute;lo* permite almacenar hasta 10GB.&lt;/p&gt;
&lt;p align="justify"&gt;Configuraci&amp;oacute;n de FILESTREAM Storage:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc645923.aspx"&gt;Activar FILESTREAM&lt;/a&gt; en nuestro servidor SQL Server.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Crear una base de datos &lt;a href="http://msdn.microsoft.com/en-us/library/cc645585.aspx"&gt;habilitada para FILESTREAM&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Crear una tabla con un campo de tipo varbinary(MAX) &lt;a href="http://msdn.microsoft.com/en-us/library/cc645583.aspx"&gt;habilitado para FILESTREAM&lt;/a&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p align="justify"&gt;Bien, supongamos que ya disponemos de nuestra base de datos y hemos creado una sencilla tabla para almacenar documentos. Algo parecido a esto:&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/filestream_5F00_699A8FC5.png"&gt;&lt;img height="200" width="206" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco/filestream_5F00_thumb_5F00_4EEDF3AC.png" alt="filestream" border="0" title="filestream" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;D&amp;oacute;nde los campos m&amp;aacute;s relevantes son: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;FileId&lt;/strong&gt;: Un campo Guid que identifica cada documento guardado de forma &amp;uacute;nica. &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;Document&lt;/strong&gt;: El campo varbinary(MAX) en el que vamos a volcar el array de bytes de los ficheros a almacenar.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;&lt;strong&gt;OriginalPath&lt;/strong&gt;: En realidad no es importante, pero uno de los metadatos que vamos a necesitar m&amp;aacute;s adelante es la extensi&amp;oacute;n del fichero, para que pueda ser abierta con su aplicaci&amp;oacute;n asociada (Word, Excel, Acrobar Reader, etc.)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;Vamos a ver c&amp;oacute;mo insertar documentos en dicha tabla. Nada mejor que un poco de C# y LINQ2SQL (o EF, eso es lo de menos):&lt;/p&gt;
&lt;div align="justify"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (OpenFileDialog opendialog = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; OpenFileDialog())&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    opendialog.Title = &lt;span style="color:#006080;"&gt;&amp;quot;Import document to database&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    opendialog.Filter = &lt;span style="color:#006080;"&gt;&amp;quot;All Documents|*.doc;*.docx;*.xls;*xlsx;*.ppt;*.pptx;*.pdf;*.txt&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (opendialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        var newdoc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FileStreamDocument();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        newdoc.FileId = Guid.NewGuid();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        newdoc.OriginalPath = opendialog.FileName;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        newdoc.Document = File.ReadAllBytes(opendialog.FileName);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        newdoc.ComputerName = Environment.MachineName;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        context.FileStreamDocuments.InsertOnSubmit(newdoc);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        context.SubmitChanges();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="justify"&gt;En el c&amp;oacute;digo anterior mostramos un OpenFileDialog, el usuario selecciona un fichero, leemos el contenido y creamos un FileStreamDocument para insertarlo en la BD. La belleza subyacente es que SQL Server se encargar&amp;aacute; de almacenar dichos ficheros fuera de la tabla, en el sistema de ficheros NTFS del servidor. Y adem&amp;aacute;s, de forma totalmente transparente para nosotros :-)&lt;/p&gt;
&lt;p align="justify"&gt;En los pr&amp;oacute;ximos posts veremos d&amp;oacute;nde se almacenan REALMENTE estos ficheros, c&amp;oacute;mo visualizarlos, y lo m&amp;aacute;s importante de todo, c&amp;oacute;mo editarlos y guardarlos otra vez en la base de datos de forma transparente para el usuario.&lt;/p&gt;
&lt;p align="justify"&gt;Nos leemos pronto! :-D&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=199583" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lfranco/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/Serie/default.aspx">Serie</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/2010/default.aspx">2010</category><category domain="http://geeks.ms/blogs/lfranco/archive/tags/4.0/default.aspx">4.0</category></item></channel></rss>
