<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Performance | The .NET Blog</title><link>https://thedotnetblog.com/es/tags/performance/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>es</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Tue, 26 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/es/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>.NET 11 por fin arregla la API de Procesos</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</guid><description>System.Diagnostics.Process recibe su mayor actualización en años. RunAndCaptureTextAsync, KillOnParentExit, APIs SafeProcessHandle y control total sobre la redirección de handles estándar — sin más boilerplate de deadlock.</description><content:encoded>&lt;p&gt;Todo desarrollador .NET que alguna vez ha necesitado lanzar un proceso y capturar su salida ha escrito alguna variación del mismo boilerplate peligroso: lectura async de stdout, lectura async de stderr, &lt;code&gt;WaitForExitAsync&lt;/code&gt;, sin olvidar drenar ambos streams o producirás un deadlock. Es una trampa conocida que lleva años ahí.&lt;/p&gt;
&lt;p&gt;.NET 11 finalmente lo arregla correctamente.&lt;/p&gt;
&lt;h2 id="runandcapturetextasync"&gt;RunAndCaptureTextAsync&lt;/h2&gt;
&lt;p&gt;La adición principal: un único método estático que inicia un proceso, captura stdout y stderr, y espera la salida sin producir deadlock.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAndCaptureTextAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardOutput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Una sola llamada. Sin drenaje manual de streams. Sin un &lt;code&gt;WaitForExit&lt;/code&gt; colocado cuidadosamente. Si simplemente necesitas ejecutar algo y obtener su salida, esta es la API que quieres.&lt;/p&gt;
&lt;p&gt;También existe &lt;code&gt;Process.RunAsync&lt;/code&gt; para el caso en que quieras esperar la salida sin capturar el output.&lt;/p&gt;
&lt;h2 id="killonparentexit"&gt;KillOnParentExit&lt;/h2&gt;
&lt;p&gt;Un problema común con los procesos lanzados: si el padre falla o es terminado, los procesos hijo siguen ejecutándose como huérfanos. &lt;code&gt;KillOnParentExit&lt;/code&gt; te permite declarar en el momento de iniciar el proceso que el proceso hijo debe terminar cuando el proceso padre salga.&lt;/p&gt;
&lt;p&gt;Esta es una funcionalidad que ha existido de formas específicas de plataforma (job objects en Windows, prctl en Linux), pero requería p/invoke o bibliotecas de terceros para usarla desde .NET. Ahora es una propiedad de primera clase en &lt;code&gt;ProcessStartInfo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="apis-basadas-en-safeprocesshandle"&gt;APIs Basadas en SafeProcessHandle&lt;/h2&gt;
&lt;p&gt;La nueva superficie de API ligera está construida sobre &lt;code&gt;SafeProcessHandle&lt;/code&gt; en lugar de la clase &lt;code&gt;Process&lt;/code&gt; completa. La clase &lt;code&gt;Process&lt;/code&gt; completa lleva mucho estado y es difícil de recortar — la ruta de &lt;code&gt;SafeProcessHandle&lt;/code&gt; es más amigable con el trimmer para aplicaciones que necesitan minimizar el tamaño de salida (WASM, AOT nativo).&lt;/p&gt;
&lt;h2 id="control-total-sobre-la-herencia-de-handles"&gt;Control Total Sobre la Herencia de Handles&lt;/h2&gt;
&lt;p&gt;La actualización también añade control detallado sobre qué handles hereda un proceso hijo y cómo se redirigen los handles estándar. Anteriormente podías redirigir stdin/stdout/stderr, pero no podías especificar exactamente qué handles heredar a nivel de SO. Las nuevas APIs exponen ese control.&lt;/p&gt;
&lt;h2 id="por-qué-importa"&gt;Por Qué Importa&lt;/h2&gt;
&lt;p&gt;La clase &lt;code&gt;Process&lt;/code&gt; se usa en tooling, sistemas de build, ejecutores de pruebas y cualquier aplicación que invoca otros ejecutables. La superficie de API anterior databa de .NET Framework y estaba mostrando su edad. No es un cambio que rompe compatibilidad — las APIs antiguas siguen funcionando — pero el nuevo código debería preferir la nueva superficie.&lt;/p&gt;
&lt;p&gt;Para aplicaciones recortadas o escenarios de compilación AOT, la ruta de &lt;code&gt;SafeProcessHandle&lt;/code&gt; es especialmente bienvenida. La antigua clase &lt;code&gt;Process&lt;/code&gt; arrastraba mucho código pesado en reflexión que complicaba el recorte.&lt;/p&gt;
&lt;p&gt;Post original: &lt;a href="https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/"&gt;Process API Improvements in .NET 11&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Cómo Copilot Studio Migró a .NET 10 WebAssembly y Se Volvió un 20% Más Rápido</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</link><pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</guid><description>Las mejoras de .NET 10 WASM no son solo para proyectos nuevos. Aquí está lo que Copilot Studio midió después de actualizar desde .NET 8: fingerprinting automático, WasmStripILAfterAOT por defecto y números reales de rendimiento de ejecución.</description><content:encoded>&lt;p&gt;El equipo de Copilot Studio hizo algo sobre lo que todos los desarrolladores Blazor WASM han sentido curiosidad: actualizaron una aplicación de producción de .NET 8 a .NET 10 y midieron los resultados. La publicación comparte números específicos, algo que es raro y genuinamente útil.&lt;/p&gt;
&lt;h2 id="la-actualización-fue-aburrida-eso-es-bueno"&gt;La Actualización Fue Aburrida (Eso es Bueno)&lt;/h2&gt;
&lt;p&gt;Actualizar el framework de destino, actualizar las referencias de paquetes, corregir los cambios disruptivos. Eso es todo. La compilación de .NET 10 ahora está ejecutándose en producción. La migración en sí no fue la parte interesante — los cambios en .NET 10 sí lo son.&lt;/p&gt;
&lt;h2 id="fingerprinting-automático-de-activos"&gt;Fingerprinting Automático de Activos&lt;/h2&gt;
&lt;p&gt;Anteriormente, distribuir una aplicación WASM significaba escribir scripts personalizados para renombrar los activos publicados con hashes SHA256 para la invalidación de caché. Copilot Studio tenía un script PowerShell haciendo exactamente esto — renombrar archivos, inyectar atributos &lt;code&gt;integrity&lt;/code&gt; en el cargador JavaScript, gestionar todo manualmente.&lt;/p&gt;
&lt;p&gt;En .NET 10, todo eso está integrado. Los activos publicados se marcan automáticamente con fingerprint, se importan directamente desde &lt;code&gt;dotnet.js&lt;/code&gt; y se validan con integridad sin intervención manual. El equipo eliminó el script de renombrado.&lt;/p&gt;
&lt;p&gt;Pequeño cambio en alcance, reducción significativa de complejidad.&lt;/p&gt;
&lt;h2 id="wasmstripilafteraot-ahora-está-activado-por-defecto"&gt;WasmStripILAfterAOT Ahora Está Activado por Defecto&lt;/h2&gt;
&lt;p&gt;En .NET 8, eliminar IL de los ensamblados compilados AOT era opt-in. En .NET 10 es el valor predeterminado. Después de la compilación AOT, el bytecode IL original se elimina de la salida — no se necesita en tiempo de ejecución, y mantenerlo inflaba el tamaño del paquete sin razón.&lt;/p&gt;
&lt;p&gt;Copilot Studio usa una optimización específica: distribuye tanto un motor JIT (inicio rápido) como un motor AOT (rendimiento máximo en estado estable), cargando ambos en paralelo y transfiriendo de JIT a AOT una vez que está listo. También deduplica los archivos idénticos entre los dos motores.&lt;/p&gt;
&lt;p&gt;El nuevo comportamiento de eliminación de IL significa que los ensamblados AOT ya no coinciden bit a bit con sus contrapartes JIT, por lo que menos archivos se deduplican:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET 8: 59 archivos compartidos&lt;/li&gt;
&lt;li&gt;.NET 10: 22 archivos compartidos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Resultado neto: tamaño del paquete aproximadamente un 15% mayor para el motor AOT. La descarga AOT es ~6% más lenta en LAN rápida, ~17% más lenta en 4G. Pero todo sucede en segundo plano después de que la aplicación ya es interactiva.&lt;/p&gt;
&lt;h2 id="los-números-de-rendimiento"&gt;Los Números de Rendimiento&lt;/h2&gt;
&lt;p&gt;Esta es la parte que importa:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;~20% más rápido&lt;/strong&gt; en la primera llamada (ruta fría)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~5% más rápido&lt;/strong&gt; en llamadas posteriores (ruta cálida)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Las mejoras son más visibles en &amp;ldquo;bots grandes&amp;rdquo; — agentes grandes y complejos donde domina el código compilado AOT. Para flujos de trabajo más simples la ganancia es menor.&lt;/p&gt;
&lt;h2 id="si-todavía-estás-en-net-8"&gt;Si Todavía Estás en .NET 8&lt;/h2&gt;
&lt;p&gt;La historia de migración es genuinamente simple: actualiza &lt;code&gt;&amp;lt;TargetFramework&amp;gt;&lt;/code&gt;, actualiza las referencias de paquetes, elimina cualquier script de fingerprinting personalizado, y automáticamente te beneficiarás de &lt;code&gt;WasmStripILAfterAOT&lt;/code&gt;. Si estás compilando AOT, espera ganancias de rendimiento similares.&lt;/p&gt;
&lt;p&gt;Una nota de la publicación: si cargas el runtime de .NET WASM dentro de un &lt;code&gt;WebWorker&lt;/code&gt;, establece &lt;code&gt;dotnetSidecar = true&lt;/code&gt; al inicializar.&lt;/p&gt;
&lt;p&gt;Post original: &lt;a href="https://devblogs.microsoft.com/dotnet/copilot-studio-dotnet-10-migration/"&gt;Copilot Studio gets faster with .NET 10 on WebAssembly&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>