.NET MAUI 在 .NET 11 中迁移至 CoreCLR
作者:David Ortinau,首席产品经理
原文链接:https://devblogs.microsoft.com/dotnet/dotnet-maui-moves-to-coreclr-in-dotnet-11/
从 .NET 11 Preview 4 开始,CoreCLR 正式成为 .NET MAUI 应用在 Android、iOS 和 Mac Catalyst 上的默认运行时。你的移动应用现在运行在同一套运行时之上——这套运行时同样驱动着 ASP.NET Core、Azure 服务、桌面应用,以及全球数百万生产环境负载。
Mono 成就了这一切
十五年来,Mono 一直是让 .NET 落地于从未被设计支持的平台的运行时。Miguel de Icaza 于 2001 年启动了 Mono 项目[1],目标是将 .NET 带到 Linux。此后,它发展成了一个没人能完全预料到的庞大生态。
MonoTouch[2] 于 2009 年将 C# 带到了 iPhone。MonoDroid[3] 随后在 Android 上跟进。Xamarin 将这些探索性实验打造成了一个平台,数百万开发者用它发布生产级移动应用。当微软于 2016 年收购 Xamarin 并开启通往 .NET MAUI 的旅程时,Mono 始终是底层的运行时基石。
Mono 的影响远不止于微软自己的产品。Unity[4] 基于 Mono 构建了整个脚本运行时,驱动着全球最流行的游戏引擎之一,以及数以百万计的游戏作品。Unity 也已开始向 CoreCLR 迁移[5]。Avalonia[6] 和 Uno Platform[7] 借助 Mono on WebAssembly,在浏览器和移动端实现跨平台应用交付。MonoGame[8] 承继了 XNA 的遗产,在各个平台上延续着 .NET 游戏开发的传统。Godot[9] 的 C# 脚本后端也由 Mono 驱动。
这是一片广袤的生态,而一切都可以追溯到同一个根基。
Mono 不仅让 .NET 踏足了移动端,更证明了 .NET 可以无处不在。CoreCLR 成为 .NET MAUI 的默认运行时,是这个故事的下一章,而非终章。
发生了什么变化
当你构建面向 .NET 11 的 .NET MAUI 应用时,CoreCLR 现在是 Android、iOS 和 Mac Catalyst 上 Release 和 Debug 构建的默认运行时。
这并非完全陌生的领域。从 .NET Framework 开始,我们就一直在不断将新平台纳入 CoreCLR,先是 Windows,然后是 Linux、macOS(AppKit)和 Android。.NET 11 的新鲜之处在于,我们将同一套运行时延伸到了 Android、iOS 和 Mac Catalyst——它们是 .NET MAUI 中最后仍在使用 Mono 的平台。
若想深入了解各平台的运行时与编译机制,请参阅运行时与编译[10]文档。
几点重要说明:
• 适用范围为 Android、iOS、Mac Catalyst 和 tvOS。 上述平台全部迁移至 CoreCLR。 • Blazor WebAssembly 不受影响。 WASM 继续使用 Mono,.NET 11 中不会有任何变化。 • 你可以选择回退到 Mono,如果在过渡期间遇到问题的话。
为什么选择 CoreCLR
三个原因推动了这一变化。
运行时统一。 此前,.NET 移动应用运行在 Mono 上,而服务器、桌面和云端运行在 CoreCLR 上。这种分裂意味着不同的 JIT 行为、不同的 GC 特性、不同的诊断工具链,以及不同的 Bug 类型。有了跨所有平台的 CoreCLR,你的移动应用与后端运行在同一套运行时上。一套运行时、一套工具、一套需要理解的行为。
更好的性能基础。 CoreCLR 为移动端带来了分层 JIT 编译、ReadyToRun(R2R)预编译,以及配置文件引导优化(PGO)。在整个 .NET 11 预览周期中,我们持续落地这些基础设施,包括默认部分 R2R[11] 和打包的 PGO 配置文件[12],无需修改任何代码即可改善启动性能。
跨平台 NativeAOT。 CoreCLR 是 NativeAOT 编译的基础,它能生成完全提前编译的原生二进制文件。以 CoreCLR 为默认运行时,Android 上通往 NativeAOT 的路径自然开启。在 iOS 和 Mac Catalyst 上,NativeAOT 构建于 Apple 平台历来要求的提前编译之上,现在拥有了更统一的工具链。相关工作正在 dotnet/android[13] 和 dotnet/macios[14] 中积极推进。
应当预期什么
我直说关于性能的情况。CoreCLR 配合 R2R 和 PGO,在许多应用上表现出显著改善,尤其是启动时间。对于基准的 dotnet new maui 应用,启动速度有可测量的提升。
然而,我们也看到社区反映在较大、较复杂的 Android 应用上出现了性能回退。dotnet/android#10588[15] 和 dotnet/android#10914[16] 等 Issue 记录了启动时间或应用体积增大的真实案例。在 iOS 上,团队已通过成功提交 App Store 验证了 CoreCLR,但你仍应自行测量应用的实际表现。我们认真对待这些反馈,并正在积极处理。
我们的建议:实测你的应用。 在 Release 模式下构建 Preview 4,在目标设备上测试,并与 .NET 10 基线比较启动时间和包体积。不要假设会有普遍改善,把你发现的问题提交到仓库中告诉我们。
在评估 CoreCLR 在 .NET 11 中应支持哪些架构时,我们决定不纳入一些较旧且使用较少的架构:Android x86、Android API 23 及以下版本,以及嵌入 API。Android arm32 是否支持仍在评估中。
如何回退至 Mono
如果遇到阻塞性问题,可以在我们修复期间临时切换回 Mono。在项目文件中添加以下内容:
<PropertyGroup>
<UseMonoRuntime>true</UseMonoRuntime>
</PropertyGroup>此配置适用于 Android、iOS 和 Mac Catalyst。当你遭遇兼容性问题,或影响发布时间线的不可接受的性能回退时,使用它。同时,请在 dotnet/android[17] 或 dotnet/macios[18] 提交 Issue,附上你的应用类型、包体积、启动耗时,以及尽可能提供可复现的示例。这些反馈将直接影响我们在 GA 前的优先级排序。
回退到 Mono 的选项在 .NET 11 服务期内持续可用。如有任何后续时间线变更,我们都会提前充分告知。
测试要点
以下是你进行 Preview 4 测试的验证清单:
1. 构建并发布以 Release 模式、面向 .NET 11 的应用 2. 测量启动时间(在真实设备上,包括冷启动和热启动) 3. 比较包体积(Android 的 APK/AAB,iOS 的 IPA)与 .NET 10 构建的差异 4. 测试完整应用流程,包括导航、数据加载以及所有平台特定集成 5. 在开发工作流中检查 Hot Reload 6. 验证第三方库——特别是使用反射、动态代码生成或 Mono 特定 API 的库
请注意,这些新平台上的调试器和 Hot Reload 实现目前尚不成熟,存在许多已知问题。即便如此,如果有任何行为与预期不符,请先查看 Android[19] 或 iOS/Mac Catalyst[20] 的已知问题列表,或提交新的 Issue。你的报告越可复现,我们处理起来就越快。
诊断工具
你立刻就能获得的一个实际收益,是在移动端使用完整的 .NET 诊断工具。你在服务器和桌面上使用的 dotnet-trace 和 dotnet-counters 工具,现在可以在你的 Android 设备及 iOS/Mac Catalyst 工作流中直接使用。如果你从未用这些工具剖析过移动应用,现在是个好时机。dotnet-dump 等其他工具也在考量之中。
前路展望
Preview 4 是大规模验证的起点,而非调优的终点。在接下来的预览版中,我们将持续:
• 缩小复杂应用的启动时间和包体积差距 • 扩大 R2R 和 PGO 在各平台上的覆盖范围 • 解决社区测试暴露的兼容性问题 • 推进 Android 上的 NativeAOT 支持,并在 iOS/Mac Catalyst 上持续完善
你在预览期间的反馈,决定了 11 月 GA 版本的最终形态。每一个提交的 Issue、每一份分享的性能数据、每一句"运行良好"的确认,都在帮助我们走到终点。
致谢
许多曾构建 Mono 移动支持的工程师,直接参与了将 CoreCLR 带到 Android、iOS 和 Mac Catalyst 的工作。他们的专业积累没有消失,而是被聚焦在了新的方向上。
我想向超过二十年来在 Mono 上构建一切的广大社区致以敬意。使用 Unity 和 MonoGame 的游戏开发者们。使用 Avalonia 和 Uno Platform 的跨平台团队们。早在行业其他人认可之前,就用 Xamarin 证明了 C# 属于移动端的开发者们。Mono 成就了这一切,它的基因在 CoreCLR 的移动端支持中永远延续。
Mono 带我们走到了这里。CoreCLR 将带我们继续前行。
立即开始
安装 .NET 11 Preview 4 SDK 和 .NET MAUI 工作负载:
dotnet workload install maui
将你现有的应用面向 net11.0-android、net11.0-ios 或 net11.0-maccatalyst 构建,然后开始验证。完整的 Preview 4 变更列表,请参阅 .NET 11 Preview 4 发布说明[21]。
我们迫不及待地想听到你的声音。提交 Issue,分享你的性能数据,告诉我们你的应用在 CoreCLR 上的表现如何。这是一次我们共同完成的迁移。
引用链接
[1] Miguel de Icaza 于 2001 年启动了 Mono 项目: https://tirania.org/blog/archive/2001/Jul-12.html[2] MonoTouch: https://tirania.org/blog/archive/2009/Sep-14.html[3] MonoDroid: https://tirania.org/blog/archive/2011/Apr-06.html[4] Unity: https://unity.com[5] 开始向 CoreCLR 迁移: https://docs.unity3d.com/6000.1/Documentation/Manual/dotnet-profile-support.html[6] Avalonia: https://avaloniaui.net/[7] Uno Platform: https://platform.uno[8] MonoGame: https://monogame.net/[9] Godot: https://godotengine.org/[10] 运行时与编译: https://learn.microsoft.com/dotnet/maui/deployment/runtimes-compilation[11] 默认部分 R2R: https://github.com/dotnet/maui/pull/33388[12] 打包的 PGO 配置文件: https://github.com/dotnet/maui/pull/33387[13] dotnet/android: https://github.com/dotnet/android[14] dotnet/macios: https://github.com/dotnet/macios[15] dotnet/android#10588: https://github.com/dotnet/android/issues/10588[16] dotnet/android#10914: https://github.com/dotnet/android/issues/10914[17] dotnet/android: https://github.com/dotnet/android/issues/new[18] dotnet/macios: https://github.com/dotnet/macios/issues/new[19] Android: https://github.com/dotnet/android/labels/CoreCLR[20] iOS/Mac Catalyst: https://github.com/dotnet/macios/labels/CoreCLR[21] .NET 11 Preview 4 发布说明: https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview4/dotnetmaui.md