Fix native AOT crash in ReactorApplication at XAML bootstrap#71
Merged
Conversation
Reactor-based WinUI apps published with PublishAot=true crashed at Application startup with STATUS_APPLICATION_INTERNAL_EXCEPTION (0xc000027b) inside Microsoft.UI.Xaml.dll. The crash happened when OnLaunched ran `Resources.MergedDictionaries.Add(new XamlControlsResources())` — under AOT the runtime XAML parse path that programmatic construction triggers is not safe, whereas the same type loaded via an App.xaml-compiled XBF (as App.xaml-based projects do) is safe. Fix routes XamlControlsResources through the XAML-compiled path by adding ReactorApplication.xaml as a library-level App-style companion and calling InitializeComponent() in the ReactorApplication constructor, matching the order and code path used by App.xaml-based consumers. GetXamlType now delegates to the XAML-compiler-generated Reactor_XamlTypeInfo.XamlMetaDataProvider (late-bound via Type.GetType with a DynamicDependency to survive trimming) with a hand-rolled ReactorCoreXamlMetaDataProvider as a fallback for primitives, core Microsoft.UI.Xaml types, enums and structs that the Controls-only provider does not carry. Benchmark (ARM64, 7s per cell; previously both Reactor variants crashed under AOT): WinUI.Reactor runs 18.5/8.0/5.2 FPS at 10/50/100% updates; WinUI.ReactorGrid runs 12.6/8.8/7.0 FPS. Both show ~0.1 ms average update cost — the lowest of any WinUI variant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Addresses a native AOT startup crash for Reactor-based WinUI apps by shifting XamlControlsResources loading to the XAML-compiled (XBF) bootstrap path and adjusting XAML metadata provider delegation accordingly.
Changes:
- Adds
ReactorApplication.xamland callsInitializeComponent()to load<XamlControlsResources/>via XBF instead of programmatic construction. - Updates
ReactorApplication’sIXamlMetadataProviderimplementation to prefer the XAML-compiler-generated provider (late-bound for trimming/AOT) with a fallback provider. - Adds/updates stress perf AOT publish benchmarking script and result CSVs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/stress_perf/run_bench_aot_publish.sh | New script to run 10/50/100% benchmarks against AOT-published outputs and emit CSV. |
| tests/stress_perf/benchmark_results_aot_publish.csv | Captures baseline results from the new AOT publish benchmark sweep. |
| tests/stress_perf/benchmark_results.csv | Updates the “current” benchmark results dataset. |
| src/Reactor/Hosting/ReactorCoreXamlMetaDataProvider.cs | Adds a fallback IXamlMetadataProvider for core primitives/enums/structs used during WinUI theme resource loading under AOT. |
| src/Reactor/Hosting/ReactorApplication.xaml | New application-level XAML that declares <XamlControlsResources/> in Application.Resources. |
| src/Reactor/Hosting/ReactorApp.cs | Switches to XAML-based resource bootstrap + generated metadata provider delegation; removes programmatic new XamlControlsResources() in OnLaunched. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot stopped work on behalf of
codemonkeychris due to an error
April 23, 2026 01:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reactor-based WinUI apps published with
PublishAot=truecrashed at Application startup withSTATUS_APPLICATION_INTERNAL_EXCEPTION(0xc000027b) insideMicrosoft.UI.Xaml.dll. The faulting call wasResources.MergedDictionaries.Add(new XamlControlsResources())inReactorApplication.OnLaunched— under native AOT the runtime XAML parse path that programmatic construction triggers is not safe, whereas the same type loaded via an App.xaml-compiled XBF (as App.xaml-based projects do) is safe. This affected every consumer ofReactorApp.Runthat published AOT.Fix
ReactorApplication.xaml(new) — Application-level XAML companion in the Reactor library that declares<XamlControlsResources/>inApplication.Resources. The XAML compiler precompiles this to XBF and emitsReactorApplication.g.i.cswithInitializeComponent(), matching the pattern any App.xaml-based project uses.ReactorApp.cs—ReactorApplicationconstructor now callsInitializeComponent(); removed the programmaticnew XamlControlsResources()fromOnLaunched.GetXamlTypedelegates primarily to the XAML-compiler-generatedReactor_XamlTypeInfo.XamlMetaDataProvider(late-bound viaType.GetTypewith[DynamicDependency]to survive trimming), with a hand-rolled fallback.ReactorCoreXamlMetaDataProvider.cs(new) — fallback provider covering system primitives, coreMicrosoft.UI.Xamltypes (DependencyObject,ResourceDictionary,Style,Setter,DataTemplate, …), enums referenced by theme-dictionary Setter values, and common value structs. Chained after the generated provider.The late-bound
Type.GetTypefor the generated provider is necessary because referencingReactor_XamlTypeInfo.XamlMetaDataProviderdirectly would fail the C# pre-compile that the XAML compiler runs before generating that type — classic chicken-and-egg. The[DynamicDependency]attribute keeps the generated type alive under AOT trimming.Benchmark
StressPerf.Reactor and StressPerf.ReactorGrid both previously crashed under AOT publish. Now both run cleanly end-to-end (ARM64, 7s per cell):
Update cost (~0.1 ms) is the lowest of any WinUI variant — Reactor's diffing layer + AOT is a good combination once it runs. Other AOT variants (Direct, DirectX) show small FPS wins and ~30-40 MB memory drops vs JIT builds.
Test plan
dotnet publish -c Release -r win-arm64succeeds for StressPerf.Reactor and StressPerf.ReactorGrid with 0 warnings--headlessmode and write report filestests/stress_perf/run_bench_aot_publish.shfull 10/50/100% sweep passes for all 6 variants🤖 Generated with Claude Code