<?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/it/tags/performance/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>it</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/it/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>.NET 11 finalmente risolve l'API dei Processi</title><link>https://thedotnetblog.com/it/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/it/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</guid><description>System.Diagnostics.Process riceve il suo aggiornamento più grande degli ultimi anni. RunAndCaptureTextAsync, KillOnParentExit, API SafeProcessHandle e controllo completo sul reindirizzamento degli handle standard — niente più boilerplate per i deadlock.</description><content:encoded>&lt;p&gt;Ogni sviluppatore .NET che abbia mai avuto bisogno di avviare un processo e catturarne l&amp;rsquo;output ha scritto qualche variante dello stesso pericoloso boilerplate: lettura async da stdout, lettura async da stderr, &lt;code&gt;WaitForExitAsync&lt;/code&gt;, senza dimenticare di svuotare entrambi gli stream altrimenti si va in deadlock. È una trappola ben nota che esiste da anni.&lt;/p&gt;
&lt;p&gt;.NET 11 finalmente la risolve correttamente.&lt;/p&gt;
&lt;h2 id="runandcapturetextasync"&gt;RunAndCaptureTextAsync&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;aggiunta principale: un singolo metodo statico che avvia un processo, cattura stdout e stderr, e attende l&amp;rsquo;uscita senza 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 chiamata. Nessuno svuotamento manuale degli stream. Nessun &lt;code&gt;WaitForExit&lt;/code&gt; posizionato con cura. Se hai solo bisogno di eseguire qualcosa e ottenere il suo output, questa è l&amp;rsquo;API che vuoi.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;è anche &lt;code&gt;Process.RunAsync&lt;/code&gt; per il caso in cui vuoi aspettare l&amp;rsquo;uscita senza catturare l&amp;rsquo;output.&lt;/p&gt;
&lt;h2 id="killonparentexit"&gt;KillOnParentExit&lt;/h2&gt;
&lt;p&gt;Un problema comune con i processi avviati: se il processo padre si arresta o viene terminato, i processi figli continuano a girare come orfani. &lt;code&gt;KillOnParentExit&lt;/code&gt; ti permette di dichiarare all&amp;rsquo;avvio del processo che il processo figlio deve essere terminato quando il processo padre esce.&lt;/p&gt;
&lt;p&gt;Questa è una funzionalità che esisteva in modi specifici per piattaforma (job objects su Windows, prctl su Linux) ma richiedeva p/invoke o librerie di terze parti per essere usata da .NET. Ora è una proprietà di prima classe su &lt;code&gt;ProcessStartInfo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="api-basate-su-safeprocesshandle"&gt;API Basate su SafeProcessHandle&lt;/h2&gt;
&lt;p&gt;La nuova superficie API leggera è costruita attorno a &lt;code&gt;SafeProcessHandle&lt;/code&gt; piuttosto che alla classe &lt;code&gt;Process&lt;/code&gt; completa. La classe &lt;code&gt;Process&lt;/code&gt; completa porta molto stato ed è difficile da eliminare — il percorso &lt;code&gt;SafeProcessHandle&lt;/code&gt; è più adatto al trimmer per le applicazioni che devono minimizzare le dimensioni dell&amp;rsquo;output (WASM, AOT nativo).&lt;/p&gt;
&lt;h2 id="controllo-completo-sullereditarietà-degli-handle"&gt;Controllo Completo sull&amp;rsquo;Ereditarietà degli Handle&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;aggiornamento aggiunge anche un controllo granulare su quali handle un processo figlio eredita e come vengono reindirizzati gli handle standard. In precedenza potevi reindirizzare stdin/stdout/stderr ma non potevi specificare esattamente quali handle ereditare a livello di SO. Le nuove API espongono quel controllo.&lt;/p&gt;
&lt;h2 id="perché-è-importante"&gt;Perché È Importante&lt;/h2&gt;
&lt;p&gt;La classe &lt;code&gt;Process&lt;/code&gt; è usata in tooling, sistemi di build, test runner e qualsiasi applicazione che invoca altri eseguibili. La vecchia superficie API risaliva a .NET Framework e mostrava la sua età. Non è un cambiamento che rompe la compatibilità — le vecchie API funzionano ancora — ma il nuovo codice dovrebbe preferire la nuova superficie.&lt;/p&gt;
&lt;p&gt;Per le applicazioni trimmate o gli scenari di compilazione AOT, il percorso &lt;code&gt;SafeProcessHandle&lt;/code&gt; è particolarmente benvenuto. La vecchia classe &lt;code&gt;Process&lt;/code&gt; portava molto codice pesante di reflection che complicava il trimming.&lt;/p&gt;
&lt;p&gt;Post originale: &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>Come Copilot Studio È Migrato a .NET 10 WebAssembly e Si È Velocizzato del 20%</title><link>https://thedotnetblog.com/it/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/it/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</guid><description>I miglioramenti di .NET 10 WASM non sono solo per i nuovi progetti. Ecco cosa ha misurato Copilot Studio dopo l'aggiornamento da .NET 8: fingerprinting automatico, WasmStripILAfterAOT per impostazione predefinita e numeri reali di prestazioni di esecuzione.</description><content:encoded>&lt;p&gt;Il team di Copilot Studio ha fatto qualcosa su cui tutti gli sviluppatori Blazor WASM erano curiosi: hanno effettivamente aggiornato un&amp;rsquo;applicazione di produzione da .NET 8 a .NET 10 e misurato i risultati. Il post condivide numeri specifici, il che è raro e genuinamente utile.&lt;/p&gt;
&lt;h2 id="la-migrazione-è-stata-noiosa-questo-è-positivo"&gt;La Migrazione È Stata Noiosa (Questo è Positivo)&lt;/h2&gt;
&lt;p&gt;Aggiornare il framework di destinazione, aggiornare i riferimenti ai pacchetti, correggere le modifiche che causano interruzioni. Tutto qui. La build .NET 10 ora è in esecuzione in produzione. La migrazione stessa non era la parte interessante — le modifiche in .NET 10 lo sono.&lt;/p&gt;
&lt;h2 id="fingerprinting-automatico-degli-asset"&gt;Fingerprinting Automatico degli Asset&lt;/h2&gt;
&lt;p&gt;In precedenza, distribuire un&amp;rsquo;app WASM significava scrivere script personalizzati per rinominare gli asset pubblicati con hash SHA256 per l&amp;rsquo;invalidazione della cache. Copilot Studio aveva uno script PowerShell che faceva esattamente questo — rinominare i file, iniettare attributi &lt;code&gt;integrity&lt;/code&gt; nel loader JavaScript, gestire tutto manualmente.&lt;/p&gt;
&lt;p&gt;In .NET 10, tutto ciò è integrato. Gli asset pubblicati vengono automaticamente contrassegnati con fingerprint, importati direttamente da &lt;code&gt;dotnet.js&lt;/code&gt; e validati con integrità senza intervento manuale. Il team ha eliminato lo script di rinomina.&lt;/p&gt;
&lt;p&gt;Piccolo cambiamento nell&amp;rsquo;ambito, riduzione significativa della complessità.&lt;/p&gt;
&lt;h2 id="wasmstripilafteraot-ora-è-abilitato-per-impostazione-predefinita"&gt;WasmStripILAfterAOT Ora È Abilitato per Impostazione Predefinita&lt;/h2&gt;
&lt;p&gt;In .NET 8, rimuovere IL dagli assembly compilati AOT era opt-in. In .NET 10 è l&amp;rsquo;impostazione predefinita. Dopo la compilazione AOT, il bytecode IL originale viene rimosso dall&amp;rsquo;output — non è necessario in fase di runtime, e mantenerlo gonfiava le dimensioni del pacchetto senza motivo.&lt;/p&gt;
&lt;p&gt;Copilot Studio usa un&amp;rsquo;ottimizzazione specifica: distribuisce sia un motore JIT (avvio rapido) sia un motore AOT (massime prestazioni in stato stazionario), caricandoli entrambi in parallelo e passando da JIT ad AOT una volta pronto. Deduplica anche i file identici tra i due motori.&lt;/p&gt;
&lt;p&gt;Il nuovo comportamento di stripping dell&amp;rsquo;IL significa che gli assembly AOT non corrispondono più bit per bit alle loro controparti JIT, quindi meno file vengono deduplicati:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET 8: 59 file condivisi&lt;/li&gt;
&lt;li&gt;.NET 10: 22 file condivisi&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Risultato netto: dimensione del pacchetto circa il 15% maggiore per il motore AOT. Il download AOT è ~6% più lento su LAN veloce, ~17% più lento su 4G. Ma tutto avviene in background dopo che l&amp;rsquo;app è già interattiva.&lt;/p&gt;
&lt;h2 id="i-numeri-delle-prestazioni"&gt;I Numeri delle Prestazioni&lt;/h2&gt;
&lt;p&gt;Questa è la parte che conta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;~20% più veloce&lt;/strong&gt; alla prima chiamata (percorso freddo)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~5% più veloce&lt;/strong&gt; nelle chiamate successive (percorso caldo)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I miglioramenti sono più visibili nei &amp;ldquo;bot grandi&amp;rdquo; — agenti grandi e complessi dove domina il codice compilato AOT. Per flussi di lavoro più semplici il guadagno è minore.&lt;/p&gt;
&lt;h2 id="se-sei-ancora-su-net-8"&gt;Se Sei Ancora su .NET 8&lt;/h2&gt;
&lt;p&gt;La storia di migrazione è genuinamente semplice: aggiorna &lt;code&gt;&amp;lt;TargetFramework&amp;gt;&lt;/code&gt;, aggiorna i riferimenti ai pacchetti, rimuovi eventuali script di fingerprinting personalizzati, e beneficerai automaticamente di &lt;code&gt;WasmStripILAfterAOT&lt;/code&gt;. Se stai compilando in AOT, aspettati guadagni di prestazioni simili.&lt;/p&gt;
&lt;p&gt;Una nota dal post: se carichi il runtime .NET WASM all&amp;rsquo;interno di un &lt;code&gt;WebWorker&lt;/code&gt;, imposta &lt;code&gt;dotnetSidecar = true&lt;/code&gt; all&amp;rsquo;inizializzazione.&lt;/p&gt;
&lt;p&gt;Post originale: &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>