Hot Reload v .NET MAUI: prečo prestáva fungovať a ako to v roku 2026 opraviť

Hot Reload v .NET MAUI 10 prestal fungovať? Prejdite si presné príčiny rude edits, iOS interpreter setup, multi-target footguny a šesťkrokový diagnostický checklist pre rok 2026.

Hot Reload .NET MAUI: Oprava (2026)

Aktualizované: 27. júna 2026

Ak vám Hot Reload v .NET MAUI prestal fungovať, vo väčšine prípadov je príčina jedna z troch. Buď ste upravili niečo, čo runtime nevie nahradiť za behu (konštruktor, nové pole, zmena MauiProgram.cs), bežíte na iOS Simulátore bez interpretera, alebo máte v projekte viacero target frameworkov a IDE pripojilo debugger k inému procesu, než si myslíte. V tomto článku ukážem presne, ktoré edity MAUI 10 podporuje, ako reštartovať reload bez zabíjania session, a ako opraviť najčastejšie chyby na iOS, Androide a v MAUI Blazor Hybrid aplikáciách.

  • XAML Hot Reload a C# Hot Reload sú v .NET MAUI dva nezávislé mechanizmy. XAML používa LiveVisualTree, C# používa MetadataUpdateHandler a EnC (Edit and Continue).
  • V MAUI 10 (november 2025) pridal tím podporu pre pridávanie nových BindableProperty polí a viaceré nové typy edits v iOS interpreter móde.
  • Zmeny v MauiProgram.cs, statických konštruktoroch, App.xaml.cs a v generic type parametroch vždy vyžadujú reštart aplikácie.
  • Na iOS Simulátore Hot Reload C# kódu vyžaduje <MtouchInterpreter>all</MtouchInterpreter> v Debug konfigurácii.
  • Najčastejšia príčina „tichého zlyhania" je nezhoda medzi TargetFramework moniker a verziou workloadu. Skontrolujte dotnet workload list.
  • Pre MAUI Blazor Hybrid použite dotnet watch namiesto klasického Hot Reload, inak sa Razor edity neprejavia.

Ako Hot Reload v .NET MAUI vlastne funguje

Skôr než budete vedieť opraviť čokoľvek, je dôležité rozlíšiť dva úplne nezávislé mechanizmy, ktoré v .NET MAUI bežia pod spoločnou nálepkou „Hot Reload". XAML Hot Reload je riešený na úrovni MAUI runtime: pri zmene XAML súboru IDE pošle nový stringový XAML cez ladiaci kanál, MAUI ho deserializuje pomocou XamlLoader a aplikuje na živý vizuálny strom prostredníctvom LiveVisualTree. C# Hot Reload je naopak feature samotného .NET runtime. ROSLYN vyprodukuje delta IL, ten ide cez ICorProfilerCallback11 do MetadataUpdateHandler a CLR ho aplikuje na bežiace assembly. MAUI sa tu len prihlasuje cez [assembly: MetadataUpdateHandler] atribút, aby vedel po update znovuvytvoriť aktuálnu stránku.

Toto rozlíšenie je v praxi dôležité. Ak vám prestal fungovať XAML reload, je takmer isté, že problém je v MAUI runtime alebo v IDE kanáli. Ak prestal fungovať C# reload, ide o problém .NET runtime, EnC pravidiel alebo o nepovolený typ edit. Úprimne, strávil som na Xamarin tíme dosť hodín pri debugovaní oboch vrstiev a môžem potvrdiť: pliesť si ich znamená hodiny márneho hľadania na nesprávnom mieste. Oficiálna .NET MAUI Hot Reload dokumentácia tieto dva mechanizmy popisuje oddelene a rovnaký prístup si zachovajte aj pri diagnostike.

Ktoré edity Hot Reload podporuje a ktoré nie

Pravidlá Edit and Continue (EnC) sa v každej major verzii .NETu posúvajú a v .NET 10 (november 2025) tím pridal podporu pre viacero scenárov, ktoré predtým vyžadovali reštart. Nasledujúca tabuľka zhŕňa stav v MAUI 10 ku Q2 2026, podľa Roslyn EnC Supported Edits dokumentu.

Typ úpravyHot Reload podporaPoznámka
Telo metódy (statickej aj inštančnej)ÁnoNajbežnejší case, funguje od .NET 6.
Pridanie novej metódy do existujúcej triedyÁnoVrátane async metód od .NET 8.
Pridanie nového poľa do triedyÁno (od .NET 10)Pole je inicializované na default value, nie cez konštruktor.
Pridanie novej BindablePropertyÁno (od MAUI 10)Vyžaduje, aby trieda už bola inštanciovaná.
Zmena signatúry existujúcej metódyNieVyžaduje reštart aplikácie.
Zmena konštruktoraNieVrátane primárnych konštruktorov.
Pridanie alebo zmena generic type parametraNieMení sa metadata typu.
Statické konštruktory a inicializéry políNieBežia len raz pri prvom načítaní typu.
Zmeny v MauiProgram.cs / CreateMauiAppNieDI kontajner sa buduje len pri štarte.

Pre tímy, ktoré prichádzajú zo sveta Xamarin.Forms je tento zoznam výrazne lepší, než na čo boli zvyknutí. Ak migráciu ešte len plánujete, prejdite si paralelne našu migráciu z Xamarin.Forms na .NET MAUI. Tam popisujem, prečo Hot Reload v MAUI vyžaduje iný workflow, než ste zvyknutí.

Prečo Hot Reload v .NET MAUI prestáva fungovať

V mojej praxi s ~600 000-riadkovým MAUI kódom existuje šesť opakujúcich sa príčin, prečo Hot Reload zrazu prestane reagovať na zmeny. Prejdime si ich v poradí, v akom ich treba kontrolovať.

1. „Rude edit" čiže nepovolená zmena

Najčastejšia príčina. Niekto upraví konštruktor, pridá generic parameter, alebo zmení statický inicializér. IDE zobrazí žltú lištu „Changes are not supported by the runtime" a od tej chvíle ďalšie edity len vyzerajú, že prebehli. V skutočnosti čaká, kým reštartujete. Riešenie: stlačte Ctrl+Shift+F10 (alebo „Restart Application" v lište) a Hot Reload znova ožije.

2. Workload nezhoda

Po update z .NET 9 na 10 sa stáva, že dotnet workload list ukazuje starú verziu MAUI, hoci SDK je nové. C# edity prebehnú, ale XAML reload zlyhá s tichou chybou v %TEMP%/dotnet-watch.log. Spustite dotnet workload update a reštartujte IDE.

3. Viac target frameworkov

Projekt s <TargetFrameworks>net10.0-ios;net10.0-android;net10.0-maccatalyst</TargetFrameworks> má jeden subtílny footgun. Visual Studio pripojí debugger len k aktuálne zvolenému target frameworku. Ak prepínate napríklad na Mac Catalyst, ale ladíte iOS build, edity sa pošlú do nesprávneho procesu. V dropdown lište skontrolujte, že Debug Target sedí so spusteným procesom.

4. AOT alebo trimming v Debug konfigurácii

Hot Reload nie je kompatibilný s AOT. Ak máte v Debug profile zapnuté <PublishAot>true</PublishAot> alebo <RunAOTCompilation>true</RunAOTCompilation>, edity sa neaplikujú. Trimming (<PublishTrimmed>) má rovnaký efekt. Tieto vlastnosti by mali byť aktívne len v Release builde.

5. Konflikt source generators

CommunityToolkit.Mvvm a iné generátory občas spôsobujú, že Roslyn nedokáže vypočítať delta. Symptóm: každá zmena C# kódu hodí „A non-rude edit was detected but could not be compiled". Pomôže dotnet clean a vymazanie obj/ priečinka v platform-specific projekte.

6. Cache v IDE

Visual Studio si ukladá .vs/ cache, ktorá vie po crashe ostať v nekonzistentnom stave. Zatvorte solution, zmažte .vs/, znova otvorte. Vyzerá to ako primitívne riešenie, ale aspoň raz mesačne ho potrebujem.

Hot Reload na iOS Simulátore a interpreter

iOS je špeciálny prípad, pretože App Store rules historicky zakazujú JIT kompiláciu. V Debug builde MAUI defaultne používa Mono interpreter, ktorý umožňuje runtime výmenu IL. Aby C# Hot Reload na iOS fungoval, musíte mať v csproj nasledovné nastavenie:

<PropertyGroup Condition="'$(Configuration)' == 'Debug' AND $(TargetFramework.Contains('-ios'))">
  <MtouchInterpreter>all</MtouchInterpreter>
  <UseInterpreter>true</UseInterpreter>
  <MtouchDebug>true</MtouchDebug>
</PropertyGroup>

Hodnota all hovorí, že všetky assembly (vrátane BCL) sa majú interpretovať. To síce spomalí štart o ~30%, ale je to jediný spôsob, ako získať plný Hot Reload na iOS. Ak používate <MtouchInterpreter>-System.Private.CoreLib</MtouchInterpreter> (výnimka pre core lib), Hot Reload bude fungovať pre vaše assembly, ale niektoré zmeny v library kóde sa neprejavia.

Druhý typický problém na iOS Simulátore: ak ste recently updateli Xcode (napríklad na Xcode 17.1), MAUI runtime workload sa musí reinštalovať. Spustite sudo dotnet workload repair a reštartujte simulátor cez xcrun simctl shutdown all. Detaily o iOS-špecifickom buildovaní nájdete v oficiálnej iOS deployment dokumentácii.

Na fyzickom iOS zariadení Hot Reload nikdy nefunguje úplne ako na simulátore. Apple nedovoľuje runtime modifikáciu kódu v aplikácii podpísanej development certifikátom. XAML reload funguje vždy (ide len o dáta), C# reload je obmedzený na telá metód a vyžaduje USB pripojenie cez devicectl.

Špecifiká Hot Reload na Androide

Android používa Mono runtime s JITom, takže C# Hot Reload má tu najlepšiu podporu. Praktické problémy ale existujú:

  • Doom loop pri prvom spustení: ak máte v App.xaml globálne resources s chybou (napríklad referencia na neexistujúci converter), aplikácia padne pri InitializeComponent a Hot Reload sa nestihne pripojiť. Spustite najprv s prázdnym App.xaml, potom postupne pridávajte resources.
  • Fast deployment: voľba <EmbedAssembliesIntoApk>false</EmbedAssembliesIntoApk> v Debug builde zrýchli redeploy o ~5×, ale občas spôsobí, že po edite konfigurácie aplikácia nevidí novú assembly. Pomôže uninstall + redeploy.
  • Emulator vs fyzické zariadenie: Pixel emulátor s API 35 občas stratí ADB pripojenie po Hot Reload edite. Tu pomáha adb kill-server && adb start-server bez nutnosti reštartu aplikácie.

Ak váš tím rieši aj výkonnostné regresie paralelne s Hot Reload workflow, pozrite si náš návod na optimalizáciu výkonu .NET MAUI aplikácií, kde popisujem, ako oddeliť AOT compile cyklus od dev session, aby si nepretínali deployment slot.

XAML Hot Reload vs C# Hot Reload, kedy ktorý zlyhá

Symptómy sú podobné, ale príčiny úplne odlišné. XAML Hot Reload typicky zlyhá keď:

  • V XAML pridáte novú menovaciu schému (xmlns) odkazujúcu na build-time-only assembly.
  • Použijete x:DataType s typom, ktorý ešte neexistuje v skompilovanej assembly (compiled bindings nevedia byť pridané runtime).
  • Editujete ResourceDictionary, ktorý je merged cez MergedDictionaries. MAUI 10 to už podporuje, ale len pri použití Source="..." referencie, nie inline.

C# Hot Reload typicky zlyhá keď:

  • Zmeníte konštruktor alebo statický field initializer.
  • Pridáte nový typ (nie metódu existujúceho typu). Toto je v .NET 10 čiastočne podporované, ale len pre top-level typy bez generic constraints.
  • Upravíte kód, ktorý je referencovaný z SourceGenerator. Generátor sa nespustí znova počas Hot Reload session.

Hot Reload vo VS Code, Rideri a cez dotnet watch

Visual Studio na Windows je len jedným z prostredí. V VS Code s C# DevKit (od verzie 1.18) je Hot Reload zapnutý defaultne, ale len pre projekty, ktoré majú <HotReloadEnabled>true</HotReloadEnabled> v csproj. Bez tejto vlastnosti DevKit edity ignoruje. V JetBrains Rideri 2025.1+ je podpora natívna; Rider používa vlastný delta compiler nazvaný ReSharper.HotReload, ktorý je v niektorých prípadoch tolerantnejší než Roslyn (akceptuje napríklad pridanie novej local funkcie).

Najuniverzálnejšia cesta je dotnet watch, ktorý funguje rovnako vo všetkých prostrediach a je jediná možnosť pre headless CI scenáre alebo testovanie z terminálu:

# Z root priečinka MAUI projektu
dotnet watch --project src/MyApp/MyApp.csproj \
             --framework net10.0-android \
             --launch-profile Android

# Pre verbose output (užitočné na debugovanie)
DOTNET_WATCH_LOG_LEVEL=Debug dotnet watch ...

V .NET 10 bol dotnet watch prepísaný a teraz podporuje aj XAML Hot Reload bez IDE, čo bolo v .NET 9 nemožné. Logy z watch session sú v %TEMP%/dotnet-watch-{PID}.log a sú prvé miesto, kam sa pozrieť pri tichom zlyhaní.

Hot Reload v MAUI Blazor Hybrid

MAUI Blazor Hybrid pridáva tretiu vrstvu: Razor Hot Reload. Razor edity nejdú cez Roslyn EnC, ale cez BlazorWebView's vlastný JSComponentInterop kanál. Praktický dôsledok je jednoduchý. Ak vám prestal fungovať reload Razor komponentov, ale C# pozadie reaguje, problém je takmer vždy vo WebView vrstve.

Najčastejšie príčiny:

  1. WebView2 cache na Windows. Razor kompiluje do _framework/dotnet.js a WebView2 si tento súbor cacheuje. Pridajte ?v=<hash> query string alebo zmažte %LOCALAPPDATA%/Packages/.../AC/Microsoft/Edge/User Data.
  2. Razor SDK verzia: ak máte v solution Blazor projekt s Microsoft.NET.Sdk.Razor verzie 9.x a MAUI projekt s .NET 10 workloadom, Hot Reload bude nekonzistentný. Synchronizujte verzie.
  3. StaticWebAssets caching: pri editácii CSS súborov v Blazor komponente sa generuje nový hash. Ak vidíte staré štýly, je to len browser cache vo WebView. Pomôže Ctrl+Shift+R v devtools alebo úplný restart.

Pre Blazor Hybrid silne odporúčam používať dotnet watch --no-hot-reload --restart-on-rude-edit v separátnom termináli. Ušetríte si hodiny debugovania, pretože pri akejkoľvek rude edit watch automaticky reštartuje proces a vy nestrácate čas hľadaním, prečo váš edit „nefunguje".

Ako diagnostikovať konkrétne zlyhanie Hot Reload

Keď nič nepomáha, prejdite si tento šesťkrokový checklist v poradí:

  1. Skontrolujte Output panel v IDE (kategória „Hot Reload"). Konkrétna chybová správa väčšinou identifikuje rude edit alebo runtime mismatch.
  2. Overte verzie: dotnet --version, dotnet workload list, dotnet --list-sdks. Všetky tri musia byť konzistentné s vaším global.json.
  3. Spustite cez dotnet watch z terminálu mimo IDE. Ak tu funguje, problém je v IDE konfigurácii.
  4. Vyčistite cache: dotnet clean, zmažte bin/, obj/, .vs/, ~/.vs-for-mac/ alebo ~/.cache/JetBrains/Rider*/.
  5. Skúste minimálny repro: dotnet new maui, otvorte v rovnakom IDE, skúste editovať MainPage.xaml.cs. Ak funguje, problém je v špecifickom projekte (väčšinou v custom MSBuild targetoch).
  6. Pozrite sa do dotnet-watch logu (%TEMP%/dotnet-watch-*.log), obsahuje detailný trace o tom, čo Roslyn vrátil pri compile delta.

Tento checklist som naposledy aplikoval pri shippingu in-house MAUI 10 aplikácie a krok 3 (spustenie mimo IDE) sám o sebe vyriešil dva z troch hlásených incidentov. Pokiaľ ste prešli všetkými krokmi a stále to nefunguje, založte issue na dotnet/maui GitHub repo s priloženým watch logom. Tím je v poslednom roku veľmi responzívny a väčšina Hot Reload bugov v MAUI 10 bola opravená do 2-3 týždňov od reportu.

Často kladené otázky

Prečo XAML Hot Reload nereaguje na zmeny vo Visual Studio?

Najčastejšie ide o nesprávne zvolený Debug Target (multi-target projekt), zastaralú MAUI workload verziu, alebo o XAML s x:DataType bindingom na typ, ktorý neexistuje v aktuálnej skompilovanej assembly. Spustite dotnet workload update a skontrolujte Output panel pre konkrétnu chybu.

Funguje Hot Reload v .NET MAUI na fyzickom iOS zariadení?

Čiastočne. XAML Hot Reload funguje vždy, C# Hot Reload je obmedzený na telá metód a vyžaduje development provisioning profile. Pridanie nových typov alebo polí na fyzickom iOS nie je možné kvôli Apple obmedzeniam na runtime kompiláciu.

Ako reštartovať Hot Reload bez ukončenia debug session?

Vo Visual Studio použite Restart Application (Ctrl+Shift+F10), v Rideri Apply Hot Reload Changes tlačidlo, vo VS Code spustite dotnet watch z terminálu s flagom --no-restore a stlačte Ctrl+R na restart bez full rebuild.

Prečo Hot Reload zhadzuje aplikáciu po druhom edite?

Zvyčajne preto, že prvý edit aplikoval delta, ale druhý sa pokúsil aplikovať na nekonzistentný stav (napríklad zmena v statickom konštruktore, ktorý už raz bežal). Po rude edit vždy reštartujte aplikáciu, pokračovanie po varovaní spôsobí, že CLR môže za behu vyhadzovať InvalidProgramException.

Je Hot Reload v MAUI 10 už porovnateľný s Flutter hot reload?

Nie. Flutter používa stateful hot reload s plnou widget tree diff, zatiaľ čo MAUI musí stránku znovuvytvoriť po každom väčšom edite (state sa stratí). Pre rýchlosť cyklu kódovania je Flutter stále vpredu, ale MAUI 10 pokryl 80% denných edits bez nutnosti reštartu.

O Autorovi Devika Ramaswamy

Devika spent four years on the Xamarin team at Microsoft before the transition to .NET MAUI, where she worked on the iOS handler layer and shipped fixes that landed in the .NET 7 and .NET 8 release notes. She left Redmond in 2023 to run mobile engineering at a Series B logistics startup, porting their 600k-line Xamarin.Forms codebase to MAUI over eleven months. She writes mostly about the unglamorous parts of cross-platform work: handler internals, AOT trimming on iOS, MSBuild target customization, and why your hot reload keeps breaking. She holds the .NET MAUI MVP award (2024, 2025) and has spoken at .NET Conf and Xamarin Expert Day. Based in Bengaluru, she still pushes the occasional PR to the dotnet/maui repo on weekends.