Mono 現狀與未來: 從 Xamarin 到 WebAssembly、Blazor 及.NET 5

本文要點:

Mono 項目始於 2001 年,是首個面向.NET 應用程序的多平臺、開源框架的項目。Xamarin 和 Blazor 分別代表了微軟在移動和 Web 應用程序方面的努力,它們都是基於 Mono 並由 Mono 提供支持的。.NET 5 為用戶提供了兩種運行時選項:高性能的 CoreCLR(用於服務器和桌面應用程序)和輕量級的 Mono(用於移動設備和 WebAssembly)。儘管 Mono 已經是.NET 的一部分了,但仍有一些開發工作要致力於改善 Mono 的運行時性能和垃圾回收器。現在.NET Core 可以與 Mono 並行安裝了,因此可以一起演進語言和運行時。

去年,微軟發佈了它的計劃,其中涉及.NET 未來以及.NET 5 的路線圖。計劃於今年年底發佈下一個主要版本,該版本旨在提供一個基於.NET Core、.NET Framework、Xamarin 及 Mono 最佳部分的多平臺、開源框架和運行時。

微軟從 2014 年開始向.NET 開源發展,當時微軟宣佈.NET Core 即將開源。然而,在此之前,.NET 就已經有了一個名為 Mono 的開源計劃。 Mono 項目始於 2001 年,最初它主要致力於為 Linux 桌面應用程序建立一個.NET 開發平臺。第一次正式版本是在 2003 年發佈的,此後該項目逐漸演進為在多個平臺和操作系統上支持.NET。

Mono 是由 Xamarin 從 2011 年開始開發的。自從該公司被微軟收購,並在 2016 年發佈.NET Core 1.0 以來,Mono 和.NET Core 一直在並行開發。根據最新發布的版本,InfoQ 採訪了 Miguel de Icaza(目前他就職於微軟,是 Xamarin 的聯合創始人,Mono 項目的原作者),討論了 Mono 的現狀及其在.NET 生態系統中的未來,以及 Xamarin 如何適合這種情況。

InfoQ:從技術上講,.NET Core 和 Mono 之間的主要區別是什麼?

Miguel de Icaza:Mono 是基於.NET Framework 的,.NET Framework 是作為 Windows 一部分發布的.NET 大版本。經過多年的發展,Mono 和.NET 都可以應用在不同的環境中。在.NET 領域中,這最終導致了.NET Core 3(這是所有未來工作和創新的基礎)的發佈,而.NET Framework 是一個長期維護的版本,它將繼續被修復和調整。 但不會有任何重大的創新。

在 Mono 的世界裡,運行時演進為支持我們所謂的“移動配置文件”,它是 API 的一個精選子集,適用於平衡用戶需求與降低獨立運行時部署的需求。這是 Xamarin .NET 努力的基礎,也是最近 WebAssembly 工作的基礎。

使用.NET 的不同場景以及使用它們的環境將開發人員必須使用的 API 集合分割開了。對於開發人員來說,沒有一種簡單的方法可以發佈在所有平臺上都可以工作的庫二進制文件。

創建能夠適用於所有不同環境的二進制庫的願望是創建.NET 標準的推動力——一個 API 的通用界面,可以在所有不同版本的.NET 上工作,無論是小型設備、移動系統,還是大型服務器。我們在這裡所採取的方法是提出一套在所有平臺上都可以平等使用的 API。但這仍然意味著我們要維護庫的不同實現。

讓.NET 的所有變體都能夠相互操作的方法就是.NET Standard,.NET Standard 的每個新版本中都添加了更多的 API,所有運行時都能確保這些 API 是通用的。當今使用最廣泛的 API 契約是 .NET Standard 2, .NET Framework、.NET Core、Xamarin 和 Mono 都支持該標準。

新的.NET Standard 2.1 版本引入了新的創新功能,但它們僅在 Mono、.NET Core 和 Xamarin 上可用,這是首個不被長期受支持的.NET Framework 所支持的.NET Standard 版本。

InfoQ:考慮到.NET Core 的最新成果以及.NET 5 的路線圖,Mono 在當前狀態的.NET 生態系統中地位如何?

de Icaza:簡短的版本是,隨著即將到來的.NET 5,用戶將能夠在所有平臺上使用相同的 API 集合,並且可以選擇運行時(CoreCLR 或 Mono)和編譯系統(靜態編譯、JIT 編譯、分層或解釋)來解決其問題的特定需求。

使用.NET 5,我們統一了類庫的實現,同時為用戶提供了兩種運行時選項。在較高的層次上,在 CoreCLR 中具有一個高吞吐量、高性能的運行時,還具有一個輕量級(但速度沒有那麼快)的 Mono 運行時。每個運行時都已針對它們最常使用的工作負載進行了調整:CoreCLR 用於服務器和桌面應用程序;Mono 用於移動和輕量級應用程序,例如 WebAssembly。

同樣在.NET 5 中,我們將有一個統一的運行時,它可以在我們支持的所有平臺上執行 C#或 F#代碼。在某些平臺上,用戶將能夠選擇他們想要使用的運行時,而在其他平臺上,將只有一個運行時可以使用。例如,對於 Windows 上的桌面應用程序,只有 CoreCLR 運行時適用,而對於 iOS,只有 Mono 運行時可用。

現在,從歷史上看,Mono 具有兩種執行和代碼生成引擎。一種是我們稱之為“mini”的代碼生成器,它可以非常快速地生成本地代碼,但是沒有進行很多優化。為了實現更好的優化,Mono 過去一直都依賴 LLVM 優化編譯器。 LLVM 以犧牲編譯時間為代價,產生漂亮的、最優的、完善的代碼。

此外,Mono 具有兩種操作模式:一種是運行時在執行時動態生成代碼(我們稱之為 JIT 編譯),另一種是運行時提前編譯代碼(基本上是靜態編譯)。提前(AOT)編譯系統用於不允許動態代碼生成的平臺(例如 iOS 或視頻遊戲機),或者必須提高啟動性能的平臺(低端手機上的某些 Android 應用)。

Mono 可以在純 JIT、混合 AOT/JIT 或 AOT 模式下運行,具體取決於平臺的要求或用戶的需求。因此,通常會使用 LLVM 提前編譯一些核心庫,例如,在保留用戶代碼可以動態編譯 (JIT) 的情況下,為這些庫生成最佳的代碼。

需要純 AOT 的系統有一個缺點,那就是.NET 的動態功能不可用(例如,動態實例化類型、使用 C# dynamic 關鍵字、或動態加載代碼等)。因此,我們著手解決這個問題。

去年,我們在 Mono 中引入了一個新的執行引擎和模式——一個解釋器。事實證明,該解釋器非常有用,這不僅是因為它能夠帶來動態性(以前缺少動態性),允許我們將一個小的運行時部署到 WebAssembly,而且還能夠使我們為用戶帶來一些“Hot”之類的功能,比如熱加載和熱重啟。

一旦我們擁有三個具有不同配置的引擎,就有必要帶來一個分層編譯系統,該系統允許 Mono 運行時根據代碼的使用方式動態調整要使用的代碼生成引擎。並使用啟動時間、內存使用率和長期性能。這是一個活躍的研究領域,我們也希望能夠在該領域調整參數、學習或向用戶提供解決方案。

.NET 5 的好處在於,.NET 5 的所有功能都可以在所有平臺上使用,用戶無需調整或更改任何內容。開箱即用的體驗已經配置為全面匹配最佳可能的配置。

InfoQ:Xamarin 和 Blazor 有什麼區別?

de Icaza:Xamarin 是我的初創公司,專注於幫助.NET 開發人員實現移動化。我們使用 Xamarin 作為一系列產品的品牌,從開發工具到在線服務都使用該品牌。到目前為止,在線服務已被整合到 Azure DevOps 中了。

Xamarin 開發工具包括原生 SDK 和 Xamarin.Forms。原生 SDK 允許開發人員瞄準 Android 和 iOS,並使用.NET 平臺中的所有原生功能。 Xamarin.Forms 是一個跨平臺的 UI 工具包,它使開發人員可以一次定義其用戶界面,並將相同的代碼映射成目標平臺的本機習慣用法。Blazor 是一種通過 C#構建交互式 Web 應用程序的新方法,它將一些最易於使用和最受歡迎的 Web 開發模式引入到了.NET。

開發人員可以構建 Blazor 應用程序,並可以選擇邏輯運行的位置,它可以運行在由 ASP.NET 提供支持的服務器上,也可以完全運行在客戶端上(為此,我們使用 WebAssembly 在瀏覽器內部運行一個.NET 運行時)。值得注意的是,在 WebAssembly 上支持.NET 的工作,當時是由 Xamarin 的 Mono 團隊完成的,但是編程模型完全是由 Blazor on WebAssembly 開發團隊構思出來的。 Mono 只是提供了執行它們代碼的方法。

InfoQ:是否可以將 Mono 與其他微軟的.NET IDE(Visual Studio、VS Code 等)一起使用呢?

de Icaza:當然可以。儘管大多數問題都是在展望.NET 5 的未來,但是現在,在移動設備、Xamarin 上構建支持.NET 的應用程序,或構建針對 WebAssembly 的 Blazor 應用程序,Mono 都是它們的引擎。這些功能在 Visual Studio 和 Visual Studio Code 也是開箱即用的。

除了微軟官方支持的配置之外,Mono(作為一個開源項目)仍然支持“ .NET Framework”兼容模式,並且可以與 Mac 上的 Visual Studio 或 Linux 上的 MonoDevelop 一起使用,以構建.NET Framework 應用程序。 這的確是我業餘時間做的一些工作,比如 TensorFlowSharp、TorchSharp(PyTorch for .NET 的綁定)和 gui.cs(一個用戶界面系統,可用於使用.NET 構建文本用戶界面)。

InfoQ:還有一些其他與.NET Core 相關的框架,比如 EF Core、ASP.NET Core 等。這些框架是否與 Mono 兼容呢?

de Icaza:使用.NET 5,它們都是受支持的。在.NET 5 之前,像 ASP.NET Core 之類的東西無法與 Mono 一起使用,這主要受限於與它相關的工具,而不是受限於運行時。

例如,EF Core 是面向移動應用程序用戶最喜歡的工具,它利用了.NET Standard,可以在 Mono 上開箱即用。

InfoQ:.NET 生態系統中,Mono 的未來是什麼?

de Icaza:現在,它已經從獨立工作中畢業,逐步發展成為了整個.NET 的一部分。現在.NET 將會有一個單一發行版,該發行版會針對我們多年來積累的每個平臺。我對開源社區多年來的支持工作感到非常自豪,也對我們團隊持續集成這些 VM 的工作感到自豪。

現在出現了一些引人入勝的發展。例如,就在今天,在使用本地配置運行 TechEmpower 基準測試時,我看到使用靜態編譯和 LLVM 的 Mono,現在可以與 CoreCLR 的性能相匹配了。

這對於 Mono 來說是一個重要的里程碑,因為當我們開始這項工作時,Mono 離我們的目標還很遠,甚至不在同一個球場上。但是,我們開始研究是什麼導致了 Mono 的性能下降,分析並測量,直到我們找到了大多數的罪魁禍首,然後我們才到達這個位置。

Mono 歷來都有一個精確的垃圾回收器,該垃圾回收器輕量、高效, 適用於移動設備,但是對於這些擁有許多 CPU 和大型內存子系統的新計算機而言,它的擴展性卻不佳。因此,我們現在有了一個使用 CoreCLR GC 的 Mono 的原型,這是一個針對 Mono 本身可高度擴展的 GC。我希望我們將來能夠為用戶提供 GC 選項。

除此之外,世界看起來越來越像一個統一的 VM,開箱即用地支持 C#和 F#,這是擺在我們面前最令人興奮的工作。

到目前為止,將我們的語言和運行時一起演進是很困難的,因為演進運行時需要演進世界上每臺 Windows 計算機上附帶的運行時。為了避免迴歸共享框架(由許多用戶共享),許多風險緩解流程已經就位,並且這些流程阻止了一體化進程中的大膽變革。

現在 .NET Core 可以並行安裝了,並且可以按照用戶需要的頻率進行升級,我們有了千載難逢的機會來共同演進語言和運行時,而且你已經可以看到其中的一些東西了。一些功能,例如接口中的默認方法實現,以及對整個類庫進行改造以使其可為空引用,這是最近的一些開發,但是還有更多的功能有待開發,因此還會有很多機會將被解鎖。


分享到:


相關文章: