<?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/pl/tags/performance/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>pl</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/pl/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>.NET 11 w końcu naprawia API Procesów</title><link>https://thedotnetblog.com/pl/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/pl/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</guid><description>System.Diagnostics.Process otrzymuje największą aktualizację od lat. RunAndCaptureTextAsync, KillOnParentExit, API SafeProcessHandle i pełna kontrola nad przekierowaniem standardowych uchwytów — koniec z powtarzającym się kodem obsługi deadlocka.</description><content:encoded>&lt;p&gt;Każdy deweloper .NET, który kiedykolwiek musiał uruchomić proces i przechwycić jego wynik, napisał jakąś wariację tego samego niebezpiecznego powtarzającego się kodu: asynchroniczny odczyt z stdout, asynchroniczny odczyt z stderr, &lt;code&gt;WaitForExitAsync&lt;/code&gt;, nie zapomnij opróżnić obu strumieni, albo dostaniesz deadlock. To dobrze znana pułapka, która istnieje od lat.&lt;/p&gt;
&lt;p&gt;.NET 11 w końcu naprawia to porządnie.&lt;/p&gt;
&lt;h2 id="runandcapturetextasync"&gt;RunAndCaptureTextAsync&lt;/h2&gt;
&lt;p&gt;Kluczowe dodanie: jedna statyczna metoda, która uruchamia proces, przechwytuje stdout i stderr, i czeka na zakończenie bez deadlocka.&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;Jedno wywołanie. Bez ręcznego opróżniania strumieni. Bez ostrożnie umieszczonego &lt;code&gt;WaitForExit&lt;/code&gt;. Jeśli po prostu chcesz uruchomić coś i uzyskać wynik, to jest właśnie to API, którego szukasz.&lt;/p&gt;
&lt;p&gt;Jest też &lt;code&gt;Process.RunAsync&lt;/code&gt; dla przypadku, gdy chcesz czekać na zakończenie bez przechwytywania danych wyjściowych.&lt;/p&gt;
&lt;h2 id="killonparentexit"&gt;KillOnParentExit&lt;/h2&gt;
&lt;p&gt;Częsty problem z uruchamianymi procesami: jeśli proces nadrzędny ulega awarii lub zostaje zabity, procesy potomne nadal działają jako sieroty. &lt;code&gt;KillOnParentExit&lt;/code&gt; pozwala zadeklarować przy uruchamianiu procesu, że proces potomny powinien zostać zakończony, gdy zakończy się proces nadrzędny.&lt;/p&gt;
&lt;p&gt;Ta funkcja istniała w specyficznych dla platformy formach (obiekty zadań w Windows, prctl w Linux), ale wymagała p/invoke lub bibliotek zewnętrznych do użycia z .NET. Teraz jest właściwością pierwszej klasy w &lt;code&gt;ProcessStartInfo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="api-oparte-na-safeprocesshandle"&gt;API oparte na SafeProcessHandle&lt;/h2&gt;
&lt;p&gt;Nowa lekka powierzchnia API jest zbudowana wokół &lt;code&gt;SafeProcessHandle&lt;/code&gt;, a nie pełnej klasy &lt;code&gt;Process&lt;/code&gt;. Pełna klasa &lt;code&gt;Process&lt;/code&gt; niesie ze sobą dużo stanu i trudno ją przycinać — ścieżka &lt;code&gt;SafeProcessHandle&lt;/code&gt; jest bardziej przyjazna dla trimmera w aplikacjach, które muszą minimalizować rozmiar wyjścia (WASM, natywne AOT).&lt;/p&gt;
&lt;h2 id="pełna-kontrola-nad-dziedziczeniem-uchwytów"&gt;Pełna Kontrola nad Dziedziczeniem Uchwytów&lt;/h2&gt;
&lt;p&gt;Aktualizacja dodaje również szczegółową kontrolę nad tym, które uchwyty dziedziczy proces potomny i jak są przekierowywane standardowe uchwyty. Wcześniej można było przekierowywać stdin/stdout/stderr, ale nie można było określić dokładnie, które uchwyty dziedziczyć na poziomie systemu operacyjnego. Nowe API udostępniają tę kontrolę.&lt;/p&gt;
&lt;h2 id="dlaczego-to-jest-ważne"&gt;Dlaczego To Jest Ważne&lt;/h2&gt;
&lt;p&gt;Klasa &lt;code&gt;Process&lt;/code&gt; jest używana w toolingu, systemach budowania, uruchomieniach testów i każdej aplikacji, która wywołuje inne pliki wykonywalne. Stara powierzchnia API pochodzi z epoki .NET Framework i pokazywała swój wiek. Nie jest to zmiana łamiąca kompatybilność — stare API nadal działają — ale nowy kod powinien preferować nową powierzchnię.&lt;/p&gt;
&lt;p&gt;W przypadku przycinanych aplikacji lub scenariuszy kompilacji AOT, ścieżka &lt;code&gt;SafeProcessHandle&lt;/code&gt; jest szczególnie mile widziana. Stara klasa &lt;code&gt;Process&lt;/code&gt; przynosiła dużo kodu z ciężkimi odwołaniami refleksji, który komplikował przycinanie.&lt;/p&gt;
&lt;p&gt;Oryginalny post: &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>Jak Copilot Studio Przemigrował do .NET 10 WebAssembly i Stał się 20% Szybszy</title><link>https://thedotnetblog.com/pl/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/pl/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</guid><description>Ulepszenia .NET 10 WASM nie są tylko dla nowych projektów. Oto co zmierzył Copilot Studio po aktualizacji z .NET 8: automatyczne odciskanie palców, WasmStripILAfterAOT domyślnie i prawdziwe liczby wydajności wykonania.</description><content:encoded>&lt;p&gt;Zespół Copilot Studio zrobił coś, o co ciekawili się wszyscy programiści Blazor WASM: faktycznie zaktualizowali aplikację produkcyjną z .NET 8 do .NET 10 i zmierzyli wyniki. Post dzieli się konkretnymi liczbami, co jest rzadkie i naprawdę przydatne.&lt;/p&gt;
&lt;h2 id="aktualizacja-była-nudna-to-dobra-rzecz"&gt;Aktualizacja Była Nudna (To Dobra Rzecz)&lt;/h2&gt;
&lt;p&gt;Aktualizacja docelowego frameworka, odświeżenie odwołań do pakietów, naprawienie zmian przełomowych. To wszystko. Build .NET 10 teraz działa na produkcji. Sama migracja nie była interesującą częścią — zmiany w .NET 10 są nią.&lt;/p&gt;
&lt;h2 id="automatyczne-odciski-palców-zasobów"&gt;Automatyczne Odciski Palców Zasobów&lt;/h2&gt;
&lt;p&gt;Wcześniej dystrybucja aplikacji WASM oznaczała pisanie niestandardowych skryptów do zmiany nazw opublikowanych zasobów z hashami SHA256 dla cache-bustingu. Copilot Studio miał skrypt PowerShell robiący dokładnie to — zmiana nazw plików, wstrzykiwanie atrybutów &lt;code&gt;integrity&lt;/code&gt; do loadera JavaScript, zarządzanie wszystkim ręcznie.&lt;/p&gt;
&lt;p&gt;W .NET 10 wszystko to jest wbudowane. Opublikowane zasoby są automatycznie oznaczane odciskiem palca, importowane bezpośrednio z &lt;code&gt;dotnet.js&lt;/code&gt; i weryfikowane pod kątem integralności bez ręcznej interwencji. Zespół usunął skrypt zmiany nazw.&lt;/p&gt;
&lt;p&gt;Mała zmiana w zakresie, znaczące zmniejszenie złożoności.&lt;/p&gt;
&lt;h2 id="wasmstripilafteraot-jest-teraz-domyślnie-włączony"&gt;WasmStripILAfterAOT Jest Teraz Domyślnie Włączony&lt;/h2&gt;
&lt;p&gt;W .NET 8 usuwanie IL ze skompilowanych AOT zestawów było opt-in. W .NET 10 jest to domyślne. Po kompilacji AOT oryginalny bytecode IL jest usuwany z wyjścia — nie jest potrzebny w czasie wykonywania, a jego zachowanie niepotrzebnie zwiększało rozmiar pakietu.&lt;/p&gt;
&lt;p&gt;Copilot Studio używa specyficznej optymalizacji: dostarcza zarówno silnik JIT (szybki start), jak i silnik AOT (maksymalna wydajność w stanie ustalonym), ładując oba równolegle i przekazując z JIT do AOT, gdy jest gotowy. Deduplikuje również pliki identyczne między dwoma silnikami.&lt;/p&gt;
&lt;p&gt;Nowe zachowanie usuwania IL oznacza, że zestawy AOT nie pasują już bit po bicie do swoich odpowiedników JIT, więc mniej plików jest deduplikowanych:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET 8: 59 współdzielonych plików&lt;/li&gt;
&lt;li&gt;.NET 10: 22 współdzielone pliki&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wynik netto: rozmiar pakietu około 15% większy dla silnika AOT. Pobieranie AOT jest ~6% wolniejsze na szybkim LAN, ~17% wolniejsze na 4G. Ale wszystko to dzieje się w tle po tym, jak aplikacja jest już interaktywna.&lt;/p&gt;
&lt;h2 id="liczby-wydajności"&gt;Liczby Wydajności&lt;/h2&gt;
&lt;p&gt;To jest ważna część:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;~20% szybciej&lt;/strong&gt; przy pierwszym wywołaniu (zimna ścieżka)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~5% szybciej&lt;/strong&gt; przy kolejnych wywołaniach (ciepła ścieżka)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ulepszenia są najbardziej widoczne w &amp;ldquo;dużych botach&amp;rdquo; — dużych, złożonych agentach, gdzie dominuje kod skompilowany AOT. Dla prostszych przepływów pracy zysk jest mniejszy.&lt;/p&gt;
&lt;h2 id="jeśli-nadal-jesteś-na-net-8"&gt;Jeśli Nadal Jesteś na .NET 8&lt;/h2&gt;
&lt;p&gt;Historia migracji jest naprawdę prosta: zaktualizuj &lt;code&gt;&amp;lt;TargetFramework&amp;gt;&lt;/code&gt;, odśwież odwołania do pakietów, usuń niestandardowe skrypty odciskania palców, a automatycznie skorzystasz z &lt;code&gt;WasmStripILAfterAOT&lt;/code&gt;. Jeśli kompilujesz AOT, spodziewaj się podobnych zysków wydajności.&lt;/p&gt;
&lt;p&gt;Uwaga z posta: jeśli ładujesz środowisko uruchomieniowe .NET WASM wewnątrz &lt;code&gt;WebWorker&lt;/code&gt;, ustaw &lt;code&gt;dotnetSidecar = true&lt;/code&gt; podczas inicjalizacji.&lt;/p&gt;
&lt;p&gt;Oryginalny post: &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>