NET Core 3.0 正式公布:新特性詳細解讀

2019-09-30

作者丨Richard Lander   譯者丨核子(zǐ)可(kě)樂(yuè)    策劃丨趙钰瑩

近日,.NET Core 3.0 正式發布。此次新版本包含一(yī)系列重要改進,添加了 Windows Forms 與 WPF、添加新的(de) JSON API、對 ARM64 的(de)支持能力以及全面提高(gāo)的(de)性能水平等。此外,C# 8 也是此次新版本的(de)重要組成部分,其中包含可(kě)空、異步流以及更多模式。F# 4.7 則專注于放寬語法限制,并專門匹配 .NET Standard 2.0。開發者現在可(kě)以立即将原有項目更新為(wèi) .NET Core 3.0,此次新版本與原有版本兼容,大家可(kě)以放心體驗。

QQ圖片20190930112954.png

根據微軟博客的(de)介紹,開發者可(kě)以面向 Windows、MacOS 以及 Linux 等系統平台下載 .NET Core 3.0 :

.NET Core 3.0 SDK 與運行時

Snap 安裝程序

Docker 鏡像

此外, ASP .NET Core 3.0 與 EF Core 3.0 也已經一(yī)同發布。Visual Studio 2019 16.3 與 Visual Studio for Mac 8.3 亦同時發布,且需要更新才能确保 .NET Core 3.0 與 Visual Studio 的(de)協同使用。.NET Core 3.0 為(wèi) Visual Studio 2019 16.3 中的(de)組成部分,開發者可(kě)以選擇直接升級至 Visual Studio 2019 16.3,從而立刻獲取 .NET Core。

感謝所有為(wèi) .NET Core 3.0 做(zuò)出貢獻的(de)朋(péng)友們!此次最新版本的(de)發布源自(zì)數百位團隊成員的(de)努力,也包括技術社區的(de)重大貢獻。

發行說明:

.NET Core 3.0 發行說明

.NET Core 2.2 -> 3.0 API 的(de)區别

.NET Core 3.0 貢獻者名單

GitHub 發行版

關于 .NET Core 3.0 的(de) GitHub 問題解答

1

3.0 版本,開發者需要了解什麽?

在深入探究 .NET Core 3.0 中的(de)全部新功能之前,我們首先需要強調幾項關鍵性的(de)改進與指導內(nèi)容。以下是整理(lǐ)出的(de)要點清單:

.NET Core 3.0 已經在 dot.net 以及 Bing.com 上托管了幾個月,通過了一(yī)系列嚴苛的(de)測試。衆多其他微軟團隊也将很快在生産流程當中通過 .NET Core 3.0 部署一(yī)系列大型工作負載。

多種組件的(de)性能得到顯著提升,感興趣的(de)朋(péng)友可(kě)以點擊此處參閱 .NET Core 3.0 的(de)性能改進說明。

C# 8 加入了異步流、範圍 / 索引、更多模式以及可(kě)為(wèi)空的(de)引用類型。可(kě)為(wèi)空意味着可(kě)以直接發現那些導緻 NullReferenceException 問題的(de)代碼缺陷。框架庫的(de)最底層注釋也已添加完成,以幫助了解何時為(wèi) Null。

F# 4.7 緻力于通過隐式 yield 表達式及相關語法降低(dī)某些操作的(de)實現難度。其中還包含對 LangVersion 的(de)支持,提供 nameof 并可(kě)以預覽形式打開靜态類。F# Core 核心庫現在還與 .NET Standard 2.0 相匹配。您可(kě)以點擊此處參閱 F# 4.7 發布公告中的(de)細節信息。

.NET Standard 2.1 增加了可(kě)與 .NET Core 以及 Xamarin 共同使用的(de)代碼類型集。.NET Standar 2.1 當中包含 .NET Core 2.1 以及之後版本中的(de)所有類型。

Windows 桌面應用現已面向 Windows Forms 與 WPF(開源)得到 .NET Core 支持。其中,WPF 設計器為(wèi) Visual Studio 2019 16.3 版本中的(de)組成部分。Windows Forms 設計器仍處于預覽狀态,并可(kě)通過 VSIX 下載的(de)形式獲取。

.NET Core 應用現在默認具備可(kě)執行文件。在以往的(de)發行版中,應用需要通過 dotnet 命令方啓動,例如(rú) dotnet myapp.dll。現在,可(kě)以通過應用特定可(kě)執行文件實現應用啓動,例如(rú) myapp 或者./myapp,具體視(shì)使用的(de)操作系統而定。

高(gāo)性能 JSON API 加入新版本,适用于 reader/writer、對象模型以及序列化場景等。這些 API 在 Span 基礎之上重新構建而成,且在底層使用 UTF8(而非 string 等 UTF16)。這些 API 能夠将分配需求控制在最低(dī)程度,從而提高(gāo)性能、減少垃圾收集器的(de)工作量。具體請參閱.NET Core 3.0 中的(de) JSON 未來發展說明。

默認情況下,垃圾收集器的(de)內(nèi)存占用量得到了顯著削減。對于将衆多應用程序托管在同一(yī)服務器之上的(de)使用場景,這項改進可(kě)謂意義重大。垃圾收集器本身也得到了更新,能夠利用 64 核及以上設備的(de)大量計算核心。

.NET Core 已針對 Docker 進行了增強,以使 .NET 應用程序能夠在容器中以可(kě)預測的(de)方式高(gāo)效運作。在容器配置中的(de)內(nèi)存或 CPU 資源有限時,目前的(de)垃圾收集器與線程池更新結果也能帶來更好的(de)運作效果。.NET Core docker 鏡像也變得更小,其中 SDK 鏡像的(de)瘦身效果尤其明顯。

Raspberry Pi 與 ARM 芯片現已得到支持,可(kě)配合遠程 Visual Studio 調試程序等工具實現物聯網開發。開發者可(kě)部署應用以監聽各傳感器,同時将消息或者圖像輸出至顯示器上,整個過程皆可(kě)通過新的(de) GPIO API 實現。ASP.NET 則可(kě)用于将數據公布于 API 或者以站點的(de)形式對物網設備進行配置。

.NET Core 3.0 即為(wèi)“當前”版本,我們計劃在 2019 年(nián) 11 月推出下一(yī)代 .NET Core 3.1 版本。.NET Core 3.1 将為(wèi)長(cháng)期支持(LTS)版本(周期至少為(wèi) 3 年(nián))。我們建議您首先采用 .NET Core 3.0,而後更新至 3.1 版,升級過程将非常輕松。

.NET Core 2.2 将于今年(nián) 12 月 23 日停止服務,具體情況請參閱 .NET Core 支持策略。

.NET Core 3.0 将通過 RHEL 8 的(de)紅(hóng)帽 Applicaltion Streams 交付,這也是我們與紅(hóng)帽公司多年(nián)合作的(de)最新成果。

對于希望在 Windows 上使用 .NET Core 3.0 的(de)用戶,将必須升級至 Visual Studio 2019 16.3。

對于希望在 Mac 上使用 .NET Core 3.0 的(de)用戶,将必須升級至 Visual Studio for Mac 8.3。

Visual Studio Code 用戶應始終使用最新版本的(de) C# 擴展,以确保能夠正常支持最新方案,包括與 .NET Core 3.0 的(de)匹配。

.NET Core 3.0 的(de) Azure App Serivce 部署目前正在進行當中。

.NET Core 3.0 的(de) Azure Dev Ops 部署即将推出。我們将在準備就緒之後發布更新。

平台支持

.NET Core 3.0 将在以下操作系統平台上得到支持:

Alpine: 3.9+

Debian: 9+

openSUSE: 42.3+

Fedora: 26+

Ubuntu: 16.04+

RHEL: 6+

SLES: 12+

macOS: 10.13+

Windows Client: 7, 8.1, 10 (1607+)

Windows Server: 2012 R2 SP1+

備注:Windows Forms 與 WPF 應用隻适用于 Windows 操作系統。

芯片支持情況:

x64,Windows、macOS 以及 Linux

x86,Windows

ARM32,Windows 與 Linux

ARM64,Linux (kernel 4.14+)

備注:請确保 .NET Core 3.0 ARM64 部署方案采用 Linux 內(nèi)核 4.14 或者更新版本。例如(rú),Ubuntu 18.04 能夠滿足這一(yī)條件,但 16.04 版本無法支持。

WPF 與 Windows Forms

開發者可(kě)以在 Windows 系統上利用 .NET Core 3 構建 WPF 與 Windows Forms 應用從項目起步之初,我們就制定了強大的(de)兼容性目标,旨在保證桌面應用程序能夠從 .NET Framework 輕松遷移至 .NET Core 當中。我們已經收到衆多開發人員的(de)反饋,了解到他們已經成功将自(zì)己的(de)應用遷移至 .NET Core 3.0,且整個流程非常輕松便捷。從了盡可(kě)能降低(dī)對開發人員的(de)影響,WPF 以及 Windows Forms 沒有受到任何影響,其仍可(kě)在 .NET Core 上正常運行。事實上,項目本身進行了重大調整,但我們認為(wèi)不對用戶造成影響才是最好的(de)調整方式。

下圖所示為(wèi)一(yī)款 .NET Core Windows Forms 應用:

QQ圖片20190930113120.png


Visual Studio 2019 16.3 已經支持創建能夠匹配 .NET Core 的(de) WPF 應用。其中包括新的(de)模闆、經過更新的(de) XAML 設計器以及 XMAL Hot Reload。該設計器類似于現有 XAML 設計器(能夠匹配.NET Framework),但二者在體驗上仍然略有不同。

從技術層面來看,最大的(de)區别在于面向 .NET Core 的(de)設計器采用新的(de)接口進程(wpfsurface.exe)以僅運行針對 .NET Core 版本的(de)運行時代碼。以往,.NET Framework WPF 設計器進程(xdesproc.exe)本身即為(wèi)承載設計器的(de) WPF .NET Framework 進程;由于運行時不兼容,我們無法使用 WPF .NET Framework 進程(在本示例為(wèi)中 Visual Studio)将兩個版本的(de) .NET(即 .NET Framework 與 .NET Core)加載至同一(yī)進程當中。這意味着設計器在一(yī)定程度上(例如(rú)設計器擴展)無法以同樣的(de)方式運作。如(rú)果正在編寫設計器擴展,我們建議認真閱讀 XAML 設計器擴展遷移文檔。

下圖所示為(wèi)顯示在新設計器當中的(de) WPF 應用:

微信圖片_20190930113238.png


Windows Forms 設計器目前仍處于預覽狀态,可(kě)以單獨進行下載。其将在後續更高(gāo)版本內(nèi)被添加至 Visual Studio 當中。該設計器的(de)當前預算版包含對最常用控件以及底層功能的(de)支持。我們将通過每月更新不斷對該設計器做(zuò)出更新。我們目前不建議大家将自(zì)己的(de) Windows Forms 應用程序移植至 .NET Core,特别是在高(gāo)度依賴設計器的(de)情況下。希望開發者體驗目前的(de)設計器預覽版,并積極向我們反饋問題。

另外,大家也可(kě)以利用 .NET CLI 通過命令行進行桌面應用程序的(de)創建與構建。例如(rú),您可(kě)以通過以下命令快速創建一(yī)個新的(de) Windows Forms 應用:

您也可(kě)以利用同樣的(de)流程創建 WPF 應用:

早在 2018 年(nián) 12 月,我們就将 Windows Forms 與 WPF 轉化為(wèi)開源項目。很高(gāo)興看到,目前技術社區以及 Windows Forms 及 WPF 團隊正共同努力以改進這兩套 UI 框架。在 WPF 方面,我們最初在 GitHub 庫中隻擁有少量代碼,但目前幾乎全部 WPF 代碼都已經發布至 GitHub。随着時間的(de)推移,未來還将有更多組件出現。與其他 .NET Core 項目一(yī)樣,這些新的(de)庫将成為(wèi) .NET Foundation 的(de)一(yī)部分,并遵循 MIT 開源許可(kě)。

System.Windows.Forms.DataVisualization 軟件包(包含圖表控件)目前也适用于新的(de) .NET Core 版本。大家現在可(kě)以将這些控制添加到您的(de) .NET Core WinForms 應用程序當中。該圖表控件的(de)源代碼可(kě)從 Github 上的(de) dotnet/winforms-datavisualization 處獲取。控件本身已經進行了調整,以簡化面向 .NET Core 3 的(de)移植過程,但我們并不打算對其做(zuò)出大規模更新。

Windows 原生互操作

Windows 以常規 API、COM 以及 WinRT 的(de)形式提供豐富的(de)原生 API。我們也從 .NET Core 1.0 時代起即提供對 P/Invoke 的(de)支持;在此次 .NET Core 3.0 當中,我們進一(yī)步添加了 CoCreate COM API、主動 WinRT API,以及将托管代碼以 COM 組件形式處理(lǐ)等功能。很多開發人員都就這些功能向我們提出申請,我們相信其正式推出也将給大家的(de)日常工作帶來巨大便利。

去(qù)年(nián)下半年(nián),我們宣布已經設法通過 .NET Core 實現了 Excel 自(zì)動化。那絕對是個有趣的(de)時刻。在底層,我們的(de)展示利用到 COM 互操作機制,例如(rú) NOPIA、對象等效性以及自(zì)定義編組器等等。現在,您可(kě)以在擴展示例當中親自(zì)體驗多種相關演示方案。

目前,.NET Core 3.0 隻部分支持托管 C++ 與 WinRT 互操作,完整的(de)支持能力将在 .NET Core 3.1 當中推出。

可(kě)空引用類型

C# 8.0 當中引入了可(kě)空與不可(kě)空兩種新的(de)引用類型,這意味着用戶可(kě)以對引用類型變量的(de)屬性做(zuò)出重要聲明:

某項引用不應為(wèi)空。當變量不應為(wèi)空時,則編譯器會強制執行規則以确保安全地(dì)撤銷針對空變量的(de)引用,而無需預先檢查引用目标是否為(wèi)空。

某項引用可(kě)以為(wèi)空。當變量可(kě)以為(wèi)空時,編譯器會強制執行規則以确保您已經對所引用的(de)變量是否為(wèi)空做(zuò)出檢查。

相較于無法從引用變量的(de)變量聲明當中确定設計意圖的(de)早期 C# 版本,此次發布的(de)新功能具有明顯的(de)優勢。通過添加可(kě)空這一(yī)全新引用類型,您将能夠更明确地(dì)聲明自(zì)己的(de)設計意圖,而編譯器則可(kě)以幫助您正确地(dì)完成這一(yī)目标并及時發現代碼中的(de)錯誤。

接口成員的(de)默認實現

目前,一(yī)旦接口發布完畢,您将無法對其做(zuò)出任何變更:換言之,要向其中添加新成員,我們就必然會對現有界面的(de)實現成員造成破壞。

在 C# 8.0 當中,大家可(kě)以為(wèi)某一(yī)接口成員提供主體。結果就是,如(rú)果實現該接口的(de)類沒有實現該成員(可(kě)能是因為(wèi)編寫代碼時還不存在該成員),那麽調用代碼将隻能獲得默認的(de)實現效果。

在本示例當中,ConsoleLogger 類并不需要實現對 ILogger 中的(de) Log(Exception) 重載,因為(wèi)其是通過默認實現進行聲明的(de)。現在,隻要為(wèi)現有實現成員提供默認實現,您就可(kě)以随時向現有接口添加新的(de)成員。

異步流

現在,您可(kě)以利用 IAsyncEnumerable 對異步數據流進行 foreach。這一(yī)新的(de)接口滿足了衆多開發人員的(de)長(cháng)久需求,也就是 IEnumerable 的(de)異步版本。該語言允許大家對任務進行 await foreach 以使用其元素。在産生方面,您的(de) yield return 條目可(kě)能會産生異步流。雖然聽起來似乎比較複雜,但其實際上将在實踐當中顯著簡化操作。

以下示例展示了異步流的(de)産生與使用情況。其中的(de) foreach 聲明為(wèi)異步,其本身會利用 yield return 為(wèi)調用程序産生一(yī)條異步流。這種利用 yield return 的(de)模式亦是我們推出的(de)異步流标準生産方式。

除了能夠實現 await foreach 之外,大家也可(kě)以創建出異步叠代器,例如(rú)一(yī)個能夠返回 IAsyncEnumerable/IAsyncEnumerator 并在其中同時實現 await 與 yield return 的(de)叠代器。對于需要處理(lǐ)的(de)對象,您也可(kě)以使用能夠實現 Stream 以及 Timer 等多種框架類型的(de) IAsyncDisposable。

索引與範圍

我們還創建了新的(de)語法與類型,可(kě)用于描述索引器、數組元素訪問或者可(kě)以直接進行數據訪問的(de)任何其他類型。其中包括對單一(yī)值(索引的(de)通常定義)或者兩個值(描述範圍)的(de)支持。

Index 是一(yī)種用于描述數組索引的(de)新類型。您可(kě)以從通過 int 從零開始對 Index 進行計數,也可(kě)以使用 ^ 前綴運算符創建索引。在以下示例中,我們可(kě)以同時觀察到這兩種情況:

Range 的(de)概念基本相同,其由兩個 Index 值構成,其一(yī)代表開始、其二代表結束,且可(kě)以用 x…y 的(de)範圍表達式編寫。接下來,大家即可(kě)使用 Range 索引以生成底層數據的(de)一(yī)個切片,具體如(rú)下所示:

使用聲明很多朋(péng)友可(kě)能已經厭倦了使用那些要求縮進代碼的(de)語句,對吧(ba)?沒問題,現在不會了。您可(kě)以按以下形式編寫代碼,該代碼将在當前語句塊的(de)作用域末尾添加 using 聲明,而後将對象放置在其末尾。

Switch 表達式

幾乎每一(yī)位 C# 用戶都非常喜歡 switch 語句的(de)概念,但卻不太喜歡它的(de)語法。C# 8 引入了 switch 表達式,該表達式可(kě)實現以下功能:

terser 語法

由于其屬于表達式,所以會返回一(yī)個值

與模式匹配全面集成

Switch 表達式中的(de)關鍵字為(wèi)“infix”,意味着該關鍵字位于測試值(在第一(yī)個示例中為(wèi) 0)與示例列表之間,這種形式與 Lambda 表達式非常相似。

第一(yī)個示例對各方法使用了 Lambda 語法,該語法能夠與 switch 表達式良好集成,但并非必需。

在此示例中,共有兩種模式在發揮作用。首先,0 會與 Point 類型模式匹配,而後再與內(nèi)的(de)屬性模式匹配。_ 用于描述丢棄模式,其與 switch 語句的(de)默認模式想再。

大家也可(kě)以更進一(yī)步依賴元組解構與參數位置,具體如(rú)下所示:

在本示例中,大家可(kě)以看到我們并不需要為(wèi)每一(yī)種情況定義變量或者顯式類型。相反,編譯器可(kě)以将當前正在測試的(de)元組與已經定義的(de)元組進行匹配。

所有這些模式,使得我們能夠編寫出意圖更加明确的(de)聲明性代碼,而非單純執行測試的(de)過程代碼。編譯器能夠負責實現無聊的(de)過程代碼,并保證其始終得到正确執行。

當然,在某些情況下,switch 語句的(de)實際效果可(kě)能仍然優于新的(de) switch 表達式與模式中的(de)語法形式。

速度更快的(de) JSON API

.NET Core 3.0 當中包含一(yī)個新的(de) JSON API 家族,其用于實現 reader/writer 場景、利用文檔對象模型(DOM)實現随機訪問外加一(yī)個序列化程序。大家可(kě)能已經非常熟悉如(rú)何使用 Json.NET 。新的(de) API 旨在滿足大多數同類場景需求,但內(nèi)存需求更低(dī)、執行速度更快。

簡而言之,我們希望構建一(yī)個新的(de) JSON API,從而充分利用.NET Core 中的(de)所有全新性能優勢,并以此為(wèi)基礎全面提升性能水平。很明顯,我們不可(kě)能在保持現有代碼庫(例如(rú) Jason.NET )兼容性的(de)同時達成這一(yī)目标。

下面,讓我們分層對這一(yī)新的(de) API 家族做(zuò)出闡述。

Utf8JsonReader

System.Text.Json.Utf8JsonReader 是種面向面向 UTF-8 編碼 JSON 文本的(de)高(gāo)性能、低(dī)分配、純轉發讀取器,負責從 ReadOnlySpan 當中讀取內(nèi)容。Utf8JsonReader 是一(yī)種基礎的(de)低(dī)級類型,我們可(kě)以利用它構建自(zì)定義解析器與解串器。利用新的(de) Utf8JasonReader,對 JSON 負載的(de)讀取速度将可(kě)達到以往 Json.NET 中讀取速度的(de)兩倍。另外,除非大家需要将 JSON 令牌實現為(wèi)(UTF16)字符串,否則其不會進行分配。

Utf8JsonWriter

System.Text.Json.Utf8JsonWriter 提供一(yī)種高(gāo)性能、非緩存、純轉發方式,可(kě)用于将 String、Int32 以及 DateTime 等常規.NET 類型寫入為(wèi) UTF-8 編碼 JSON 文本。與 reader 類似,writer 是一(yī)種基礎低(dī)級類型,開發人員可(kě)以利用它構建自(zì)定義序列化程序。使用新的(de) Utf8JasonWriter,JSON 負載的(de)編寫速度将比 Json.NET 寫入器高(gāo) 30% 到 80%,且不進行分配。

JsonDocument

System.Text.Json.JsonDocument 能夠對 JSON 數據進行解析,并建立隻讀文檔對象模型(DOM)功能,用以查詢該對象以支持随機訪問與枚舉。其建立在 Utf8JasonReader 基礎之上,組成數據的(de) JSON 元素可(kě)以通過由 JsonDocument 類型(被稱為(wèi) RootElement 屬性)公開的(de) JsonElement 類型進行訪問。JsonElement 當中包含 JSON 數組與對象枚舉器,外加用于将 JSON 文本轉換為(wèi)常見.NET 類型的(de) API。利用 JsonDocument,對常規 JSON 負載進行解析并訪問其中各成員的(de)速度,一(yī)般可(kě)以達到以往 Json.NET 的(de) 2 到 3 倍;而且由于數據本身大小合理(lǐ)(小于 1 MB),因此幾乎不需要進行數據分配。

JSON 序列化器

System.Text.Json.JsonSerializer 層位于高(gāo)性能 Utf8JsonReader 與 Utf8JsonWriter 之上。其負責對來自(zì) JSON 的(de)對象進行反序列化,并對指向 JSON 的(de)對象進行序列化。內(nèi)存分配得到嚴格控制,同時支持利用 Stream 以異步方式進行 JSON 讀取與寫入。

引入全新 SqlClient

SqlClient 是一(yī)款數據提供程序,您可(kě)以利用它直接利用 ADO .NET API 訪問微軟 SQL Server 以及 Azure SQL Database 等。SqlClient 已經正式發布,并通過 Microsoft.Data.SqlClient NuGet 工具包進行更新,且同時支持 .NET Freamework 與 .Net Core 應用程序。通過使用 NuGet,SQL 團隊将能夠更輕松地(dì)為(wèi) Freamework 與 .Net Core 用戶提供更新。

ARM 與物聯網支持

我們在本次發行版當中實現了對 Linux ARM64 的(de)支持,這也是對此前 .NET Core 2.1 與 2.2 版本當中面向 Linux 與 Windows 提供 ARM32 支持能力的(de)延續。雖然某些物聯網工作負載能夠發揮我們現有 x64 功能提供的(de)優勢,但仍有不少用戶強烈要求發布 ARM 支持功能。現在這一(yī)功能已經落實到位,我們也在與計劃進行大規模部署的(de)客戶開展廣泛合作。

不少利用.NET 的(de)物聯網部署場景涉及邊緣設備,且完全面向網絡。其他一(yī)些場景則要求對硬件進行直接訪問。在本次發行版中,我們添加了新的(de)功能以在 Linux 上使用串行端口,同時可(kě)利用 Raspberry Pi 等設備上的(de)數字引腳功能。該引腳使用多項協議。我們還添加了對 GPIO、PWM、I2C 以及 SPI 的(de)支持,以支持讀取傳感器數據、以無線方式交互并将文本與圖像輸出至顯示器等功能。

此功能屬于以下軟件包中的(de)組成部分:

System.Device.Gpio

Iot.Device.Bindings

作為(wèi) GPIO(及其他同類協議)支持的(de)一(yī)部分,我們審視(shì)了以往版本中的(de)原有元素。我們發現其中的(de) C# 與 Python API,在這兩種場景下 API 都屬于原生庫上的(de)打包器,而這些庫則采用 GPL 許可(kě)。我們認為(wèi)這種方法缺乏可(kě)持續性。因此,我們構建了 100% 純 C# 解決方案以實現這些協議,這意味着我們的(de) API 可(kě)以在支持 .NET Core 的(de)任何環境下運作,利用 C# 調試器(通過 sourcelink)進行調試,并支持多種底層 Linux 驅動程序(包括 sysfs、libgpoid 以及其它針對特定主闆的(de)驅動程序)。所有代碼皆遵循 MIT 許可(kě)。與現有技術相比,我們認為(wèi)這種新方法将給.NET 開發人員帶來巨大的(de)便利。

.NET Core 運行時前滾策略更新

現在,.NET Core 運行時(更具體地(dì)講,運行時綁定程序)開始提供主版本的(de)前滾選擇策略。運行時綁定程序将默認啓用面向補丁與次版本的(de)前滾功能。我們決定公開一(yī)組更為(wèi)廣泛的(de)策略,以幫助開發人員快速恢複可(kě)能存在的(de)更新問題,但原有前滾操作并不受影響。

我們發布了一(yī)項名為(wèi) RollForward 的(de)新屬性,該屬性能夠接受以下值:

LatestPatch——前滾至最新補丁版本。其會禁用 Minor 策略。

Minor ——前滾至最早次版本以解決所需次版本缺失問題。如(rú)果該次版本存在,則 LatesPatch 策略即可(kě)起效。這也是系統中采用的(de)默認策略。

Major ——前滾至最早主版本與最早次版本,以解決所需主版本缺失問題。如(rú)果該主版本存在,則随後使用 Minor 策略。

LatestMinor——前滾至最新次版本,即使存在所請求的(de)次版本亦不受影響。

LatestMajor ——前滾至最新主版本,即使存在所請求的(de)主版本亦不受影響。

Disable ——不進行前滾。僅綁定至指定版本。我們不建議大家在常規用途中使用這一(yī)選項,因為(wèi)其會禁用前滾至最新補丁後版本的(de)功能。僅建議您在測試環境中使用。

Docker 與 cgroup 限制

很多開發人員都在利用容器技術打包并運行自(zì)己的(de)應用程序。其中的(de)一(yī)大重要問題,在于容器的(de) CPU 或者內(nèi)存等資源可(kě)能受到限制。我們早在 2017 年(nián)就實現了對內(nèi)存限制功能的(de)支持,遺憾的(de)是,我們發現該實現的(de)主動性不足以将容器環境以可(kě)靠方式保持在配置限制之下,意味着即使設置了內(nèi)存限制(特别是小于 500 MB 的(de)情況),應用程序仍然有可(kě)能出現 OOM 問題。我們已經在 .NET Core 3.0 當中修複了這一(yī)問題。這一(yī)改進意義重大,我們強烈建議使用 .NET Core Docker 的(de)用戶升級至 .NET Core 3.0。

Docker 資源限制功能構建在 cgroup 基礎之上,而 cgroup 又是一(yī)項 Linux 內(nèi)核功能。從運行時的(de)角度來看,我們需要以 cgroup 基元為(wèi)目标。

大家可(kě)以利用 docker run -m 參數來限制容器的(de)可(kě)用內(nèi)存,如(rú)下所示,此示例用于創建一(yī)個基于 Alpine 且內(nèi)存容量為(wèi) 4 MB 的(de)容(而後輸出內(nèi)存限制):

我們還添加了新的(de)變更,以更好地(dì)支持 CPU 限制(–cpus)。其中包括更新運行時對十進制 CPU 值進行四舍五入的(de)方式。如(rú)果将—cpus 設置為(wèi)(足夠)接近某個較小的(de)整數(例如(rú) 1.499999999)的(de)值,則運行時會對該值進行四舍五入(這種情況下将四舍五入為(wèi) 1)。結果就是,運行時所使用的(de) CPU 數量低(dī)于需求,從而導緻 CPU 資源不足。通過對該值進行直接進位,運行時在理(lǐ)論上會增加 OS 線程調度程序的(de)壓力,但即使是在最極端的(de)情況下(–cpus=1.000000001,以往 其會被四舍五入為(wèi) 1,但現在會直接進位為(wèi) 2),我們也沒有發現 CPU 出現任何性能下降。

下一(yī)步是确保線程池遵循 CPU 限制。線程池算法中有一(yī)部分負責計算 CPU 的(de)繁忙時間,也就是計算可(kě)用 CPU 容量。通過在計算 CPU 繁忙時間當中考慮 CPU 限制,我們得以避免線程池在争用中執行的(de)各種試探操作:一(yī)種方法可(kě)能嘗試分配更多線程以增加 CPU 繁忙時間;但另一(yī)種方法則可(kě)能嘗試分配更少線程,以避免不必要的(de)線程浪費。

默認情況下降低(dī) GC 堆大小

在緻力于改善對 docker 內(nèi)存限制支持能力的(de)同時,我們也受到了啓發,并着手對通用 GC 策略加以更新,旨在為(wèi)更為(wèi)廣泛的(de)應用程序的(de)內(nèi)存使用率帶來改善(即使未運行在容器之內(nèi))。這些變更使得第 0 代預算分配能夠更好地(dì)與現代處理(lǐ)器的(de)緩存大小及緩存層級保持一(yī)緻。

我們的(de)團隊成員 Damian Edwards 注意到,ASP.NET 基準測試的(de)內(nèi)存使用量減少了一(yī)半,但其它性能指标并未出現任何負面影響。這是一(yī)項驚人的(de)進步!如(rú)他所言,這些将成為(wèi)新的(de)默認設置,且不需要對您的(de)代碼做(zuò)出任何修改(隻需采用 .NET Core 3.0 即可(kě))。

當然,我們在 ASP.NET 基準測試中觀察到的(de)內(nèi)存節約效果,可(kě)能代表 / 不代表您的(de)實際體驗。我們希望聽到更多朋(péng)友在實際應用程序內(nèi)存使用量方面觀察到的(de)結果。

改善對多處理(lǐ)器設備的(de)支持能力

基于 .NET 的(de) Windows 傳統,GC 需要配合 Windows 處理(lǐ)器組概念才能支持包含 64 塊以上處理(lǐ)器的(de)計算機。這一(yī)實現早在 5 到 10 年(nián)前的(de) .NET Framework 當中即已完成。但利用 .NET Core,我們最初選擇了 Linux PAL 以實現類似的(de)概念——雖然 Linux 當中不存在這一(yī)原生概念。此後,我們在 GC 當中放棄了這一(yī)概念,并将其轉化為(wèi) Windows APL。

GC 現在公開了一(yī)個配置開關,即 GCHeapAffinitizeRanges,用于在包含 64 個以上處理(lǐ)器的(de)計算機上指定相似的(de)掩碼。

GCLarge Page 支持

Large Pages 或者叫 Huge Pages 是一(yī)項功能,操作系統可(kě)利用其構建起大于原生頁面大小(通常為(wèi) 4K)的(de)內(nèi)存區域,從而提高(gāo)調用這些大頁面的(de)應用程序的(de)性能表現。

當發生虛拟到物理(lǐ)地(dì)址的(de)轉換時,系統會首先查詢(通常為(wèi)并行)被稱為(wèi)轉換後備緩沖區(TLB)的(de)高(gāo)速緩存,以檢查是否存在可(kě)用于所訪問虛拟地(dì)址的(de)可(kě)用物理(lǐ)翻譯,以避免進行可(kě)能占用大量資源的(de)頁面移動操作。每個大頁面翻譯都需要使用 CPU 內(nèi)部的(de)一(yī)個翻譯緩沖區。該緩沖區的(de)大小通常要比本地(dì)頁面大三個數量級;這能夠極大提高(gāo)轉換緩沖區的(de)效率,從而改善內(nèi)存在頻繁訪問下的(de)性能。在具有雙層 TLB 的(de)虛拟機當中,這一(yī)改進顯得尤為(wèi)重要。

GC 現在能夠利用 GCLargePages 選項功能進行配置,從而選擇在 Windows 上分配大頁面。利用大頁面能夠減少 TLB 遺漏,進而在總體上提高(gāo)應用程序的(de)性能;但是,這項功能也有着自(zì)己的(de)局限,應當認真考量。Bing.com 就采用了這項功能,并切實獲得了性能提升。

.NET Core 版本 API

我們在.NET Core 3.0 當中對.NET Core 版本 API 做(zuò)出改進,現在它們能夠返回您所需要的(de)版本信息。這些變更雖然在客觀上帶來了便利,但卻存在技術破壞性,而且有可(kě)能影響到依賴現有版本 API 獲取各類信息的(de)應用程序。

現在,大家可(kě)以訪問以下版本信息:

Event Pipe 改進 Event Pipe 現在支持多個會話。這意味着大家可(kě)以使用 EventListener 在進程內(nèi)使用事件,同時獲得進程外 event pipe 客戶端。

添加了新的(de) Perf Counters:

GC 中的(de)時間百分比

Gen 0 堆大小

Gen 1 堆大小

Gen 2 堆大小

LOH 堆大小

分配率

加載組件數量

ThreadPool 線程數量

鎖定争用率

ThreadPool 工作條目隊列

ThreadPool 已完成工作項比例

現在,大家可(kě)以使用同樣的(de) Event Pipe 基礎設施實現 Profiler 險别。

HTTP/2 支持

現在,我們在 HttpClinet 當中支持 HTTP/2。采用新協議是為(wèi)了滿足某些 API 的(de)要求,例如(rú) gRPC 與 Apple Push Notification Service。我們希望未來會有更多服務使用 HTTP/2 協議。此外,ASP.NET 也同樣支持 HTTP/2。

備注:首選 HTTP 協議版本将通過 TLS/ALPN 協商,并僅在服務器選擇使用 HTTP/2 時才加以使用。

分層編譯

分層編譯是 .NET Core 2.1 中的(de)一(yī)項可(kě)選功能,該功能使得運行時能夠更靈活地(dì)使用即時(JIT)編譯器,從而在啓動時獲得更佳性能并最大程度提升吞吐量。.NET Core 3.0 在默認情況下即啓用這一(yī)功能。去(qù)年(nián),我們對該功能做(zuò)出了一(yī)系列改進,包括針對各類工作負載(例如(rú)網站、PowerShell 以及 Windows 桌面應用程序)進行測試。性能确實迎來顯著提升,因此我們決定将其作為(wèi)默認選項。

IEEE 浮點改進

我們對浮點 API 進行了更新,以符合 IEEE 754-2008 修訂版的(de)要求。.NET Core 浮點項目的(de)目标,在于公開所有“必要”運算,以确保其在行為(wèi)層面符合 IEEE 提出的(de)規範。

解析與格式化修複:

正确解析并舍入任何長(cháng)度的(de)輸入。

正确解析并格式化負零。

通過進行不區分大小寫的(de)檢查,并在适用時允許使用可(kě)選前置 + 以正确解析無限與 NaN。

新的(de) Math API:

BitIncrement/BitDecrement ——對應于 nextUp 與 nextDown IEEE 運算。二者分别返回大于或者小于輸入內(nèi)容的(de)最小浮點數。例如(rú),Math.BitIncrement(0.0)将返回 double.Epsilon。

MaxMagnitude/MinMagnitude——對應于 maxNumMag 與 minNumMag IEEE 運算,二者分别返回大于或者小于輸入內(nèi)容的(de)值。例如(rú),Math.MaxMagnitude(2.0 -3.0) 将返回 -3.0。

ILogB ——對應于 logB IEEE 運算,該運算将返回一(yī)個整數值,且該值為(wèi)輸入參數的(de)以 2 為(wèi)底的(de)整數對數。實際上與 floor(log2(x)) 相同,但舍入誤差最小。

ScaleB——對應于采用整數值的(de) scaleB IEEE 運算,其相當于返回 x * pow(2,n) 的(de)值,但舍入誤差最小。

Log2——對應于 log2 IEEE 運算,返回以 2 為(wèi)底的(de)對數,且舍入誤差最小。

FusedMultiplyAdd ——對應于 fma IEEE 運算,負責執行積和(hé)熔加運算。具體而言,其通過一(yī)次運算完成(xy)+ z 運算,同時使舍入誤差最小。以 FusedMultiplyAdd (1e308, 2.0, -1e308) 為(wèi)例,其返回值為(wèi) 1e308。常規(1e308

2.0)-1e308 将返回 double.PositiveInfinity。

CopySign ——對應于 copySign IEEE 運算,其返回 x 的(de)值,但同時帶有 y 符号。

.NET 平台相關改進

我們添加了一(yī)些新的(de) API,用以訪問某些面向性能的(de) CPU 指令,包括 SIMD 或 Bit Manipulation 指令集。這些指令能夠在某些場景下實現巨大的(de)性能提升,例如(rú)更高(gāo)效地(dì)并行處理(lǐ)數據。除了公開這些可(kě)供應用程序使用的(de) API 之外,我們還開始利用相關指令對.NET 庫進行提速。

以下 CoreCLR PRs 通過實現或者使用的(de)方式展示了一(yī)部分內(nèi)部函數:

實現簡單 SSE2 硬件內(nèi)部函數

實現 SSE 硬件內(nèi)部函數

Arm64 Base 硬件內(nèi)部函數

面向 LocateFound使用 TZCNT 與 LZCNT

現可(kě)在 Linux 上支持 TLS 1.3 與 OpenSSL 1.1.1

.NET Core 現在能夠利用 OpenSSL 1.1.1 中的(de) TLS 1.3 支持能力。TLS 1.3 能夠為(wèi) OpenSSL 團隊提供多項優勢:

通過減少客戶端與服務器間的(de)往返次數縮短(duǎn)連接時長(cháng)。

通過消除各種過時及不安全的(de)加密算法、同時加密更多連接握手,以提高(gāo)安全性。

.NET Core 3. 能夠利用 OpenSSL 1.1.1、OpenSSL 1.1.0 以及 OpenSSL 1.0.2(以及您能夠在 Linux 系統上找到任何最佳版本)。如(rú)果客戶端與服務器均支持 TLS 1.3,且 OpenSSL 1.1.1 可(kě)用,則 SslStream 與 HttpClinet 類型将在使用 SslProtocols.None 時選擇 TLS 1.3(系統默認協議)。

.NET Core 後續還将在 Windows 與 MacOS 上支持 TLS 1.3——預計以自(zì)動化方式實現,敬請期待。

加密

我們增加了對 AES-GCM 以及 AES-CCM 加密機制的(de)支持,這些加密算法将通過 System.Security.Cryptography.AesGcm 與 System.Security.Cryptography.AesCcm 實現。這些算法皆屬于帶關聯數據的(de)加密認證(AEAD)算法,同時也是首批被添加至 .NET Core 當中的(de)驗證加密(AE)算法。

.NET Core 3.0 現在支持通過标準格式導入及導出非對稱公鑰與私鑰,且無需使用 X.509 證書。

所有密鑰類型(RSA、DSA、ECDsa、ECDiffieHellman)都支持 X.509 SubjectPublicKeyInfo 格式的(de)公鑰,以及 PKCS#8 PrivateKeyInfo 與 PKCS#8 EncryptedPrivateKeyInfo 格式的(de)私鑰。此外,RSA 還支持 PKCS#1 RSAPublicKey 與 PKCS#1 RSAPrivateKey。所有導出方法皆産生 DER 編碼的(de)二進制數據,而導入方法也基本相同;如(rú)果某一(yī)密鑰以文本友好的(de) PEM 格式存儲,則調用程序将需要先對內(nèi)容進行 base64 解碼,而後才能進行方法導入。

PKCS#8 文件可(kě)通過 System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo 類進行檢查。

PFX/PKCS#12 文件可(kě)分别通過 System.Security.Cryptography.Pkcs.Pkcs12Info 與 System.Security.Cryptography.Pkcs.Pkcs12Builder 進行檢查與修改。

支持新的(de)日本年(nián)号(令和(hé))

2019 年(nián) 5 月 1 日,日本開始使用新的(de)年(nián)号——令和(hé)。因此,支持日語日曆的(de)軟件(例如(rú) .NET Core)必須進行更新以支持這一(yī)新年(nián)号。.NET Core 與 .NET Framework 已經更新,現在可(kě)以正确處理(lǐ)新年(nián)号下的(de)日文日期格式與解析結果。

.NET 依賴于操作系統或其他更新以正确處理(lǐ)令和(hé)日期。如(rú)果您或者您的(de)客戶使用 Windows 系統,請下載 Windows 版本的(de)最新更新。如(rú)果您運行的(de)是 MacOS 或者 Linux,請下載并安裝支持日本新年(nián)号的(de) ICU 64.2 版本。

Assembly Load Context 改進

關于 AssemblyLoadContext 的(de)改進:

實現上下文命名

添加 ALC 枚舉功能

對 ALC 內(nèi)程序集進行枚舉的(de)功能

實現類型具體化——旨在簡化實例化(簡單場景不需要自(zì)定義類型)

通過将 AssemblyDependencyResolyer 與自(zì)定義 AssemblyLoadContext 加以結合,應用程序将能夠在加載插件的(de)過程中,從各個正确位置加載該插件所需要的(de)依賴項,且某一(yī)插件的(de)依賴項不會與其他插件的(de)依賴項發生沖突。

Assembly 可(kě)卸載性

Assembly 的(de)可(kě)制裁性是 AssemblyLoadContext 中提供的(de)一(yī)項新功能。從 API 的(de)角度來看,這項新功能具有極高(gāo)的(de)透明度,且面向部分新 API 公開。其允許開發人員對加載程序的(de)上下文進行卸載,從而釋放原本被實例化類型、靜态字段以及程序集本身所占用的(de)內(nèi)存。應用程序可(kě)以通過這種機制實現程序集的(de)永久加載與卸載,且不會引發內(nèi)存洩漏。

我們希望這項新功能被用于以下場景:

需要動态插件加載與卸載的(de)插件使用場景。

對代碼的(de)動态編譯、運行以及刷新。适用于網站、腳本引擎等。

加載程序集以進行自(zì)我檢查(例如(rú) ReflectionOnlyLoad),但在大多數情況下 MetadataLoadContext 仍然是更好的(de)選擇。

利用 MetadataLoadContext 讀取 Assembly 元數據

我們添加了 MetadataLoadContext,希望在不影響調用程序域的(de)前提下讀取 assembly 元數據。各 assembly 這以數據的(de)形式讀取,其中包括與當前運行時環境不同的(de)各類架構及平台上的(de) assembly。MetadataLoadContext 與 ReflectionOnlyLoad 存在一(yī)定交集,但後者僅适用于 .NET Framework。

MetdataLoadContext 目前通過 System.Reflection.MetadataLoadContext 軟件包發布,其屬于 .NET Standard 2.0 軟件包。

MetadataLoadContext 的(de)适用場景包括設計時功能、構建時工具與運行時點亮(liàng)功能等需要将一(yī)組 assembly 作為(wèi)數據進行檢查,并在執行檢查後釋放所有文件鎖與內(nèi)存的(de)場景。

Native Hosting 示例

.NET Core 團隊還發布了一(yī)個 Native Hosting 示例,其中展示了在本機應用程序當中托管 .NET Core 的(de)相關最佳實踐。

作為(wèi) .NET Core 3.0 中的(de)組成部分,我們現在面向 .NET Core 本地(dì)主機公開了這一(yī)原本隻通過官方 .NET Core 主機為(wèi) .NET Core 托管應用程序提供的(de)功能。此項功能主要與 assembly 加載相關,利用這項功能可(kě)幫助大家更輕松地(dì)構建能夠利用 .NET Core 完整功能集的(de)本地(dì)主機。

其他 API 改進

我們曾在 .NET Core 2.1 版本當中對 Span、Memory 以及其他相關類型做(zuò)出優化。現在,span construction、切片、解析以及格式化等常規操作的(de)執行效果将有所提升。此外,String 等類型也得到了明顯改進,能夠在與 Dictionary 及其他集合共同充當鍵時擁有更好的(de)執行效率。所有改進開箱即用,無需對您的(de)代碼做(zuò)出任何變更。

下面來看其它最新改進:

Brotli 內(nèi)置 HttpClient 支持能力

ThreadPool.UnsafeQueueWorkItem(IThreadPoolWorkItem)

Unsafe.Unbox

CancellationToken.Unregister

複雜算術運算符

Socket APIs for TCP 仍然有效

StringBuilder.GetChunks

IPEndPoint 解析

RandomNumberGenerator.GetInt32

System.Buffers.SequenceReader

默認情況下,應用程序現在具有原生可(kě)執行文件

.NET Core 應用程序現在擁有自(zì)己的(de)原生可(kě)執行文件。對于依賴框架的(de)應用程序而言,這是一(yī)項前所未有的(de)新功能。在此之前,隻有獨立應用程序具有可(kě)執行文件。這些新的(de)可(kě)執行文件,将在效果上與此前的(de)原生可(kě)執行文件保持一(yī)緻:

您可(kě)以雙擊可(kě)執行文件以啓動對應應用程序。

您可(kě)以在 Windows 上使用 myapp.exe,或者在 Linux 及 MacOS 上使用./myapp 通過命令提示符啓動應用程序。

作為(wèi) build 的(de)組成部分,新生成的(de)可(kě)執行文件将與您的(de)操作系統以及 CPU 相匹配。例如(rú),如(rú)果您使用的(de)是 Linux x64 計算機,那麽可(kě)執行文件将僅可(kě)在該類型的(de)計算機上運行——無法在 Windows 以及 Linux ARM 計算機上運行。這是因為(wèi)可(kě)執行文件使用本機代碼(例如(rú) C++)。如(rú)果要定位為(wèi)其他機器類型,則需要在發布時使用對應的(de)運行時參數。如(rú)果願意,您也可(kě)以繼續使用 dotnet 命令啓動應用程序,而不使用原生可(kě)執行文件。

利用 ReadyToRun 鏡像優化 .NET Core 應用

通過将應用程序 assemblies 編譯為(wèi) ReadyToRun(R2R)格式,可(kě)以改進 .NET Core 應用程序的(de)啓動速度。R2R 是一(yī)種提前(AOT)編譯格式,在 .NET Core 3.0 版本中以可(kě)選功能的(de)形式提供。

R2R 二進制文件能夠減少應用程序加載時 JIT 需要完成的(de)工作量,從而提高(gāo)啓動性能。二進制文件當中包含與 JIT 産生的(de)代碼相似的(de)本機代碼,能夠通過分擔 JIT 的(de)負載壓力帶來更理(lǐ)想的(de)啓動性能。R2R 二進制文件體積較大,因為(wèi)其中既包含中間語言(IL)代碼(某些情況下仍然需要此代碼),同時包含同一(yī)代碼的(de)本機版本,用以改善啓動速度。

要啓用 R2R 編譯:

将 PublishReadyToRun 屬性設置為(wèi) true。

使用 RuntimeIdentifie 顯式參數發布。

備注:在編譯應用程序 assemblies 時,生成的(de)本機代碼将特定于當前平台與架構(因此,大家在發布時必須指定有效的(de) RuntimeIdentifier)。

以下為(wèi)具體示例:

使用以下命令進行發布:

備注:RuntimeIdentifier 可(kě)設置為(wèi)其他操作系統或者芯片類型,亦可(kě)在項目文件內(nèi)進行設置。

Assembly Linking

.NET core 3.0 SDK 附帶一(yī)款工具,可(kě)通過分析 IL 與修剪未使用的(de) assemblies 以降低(dī)應用程序的(de)體積。這是 .NET Core 3.0 中的(de)另一(yī)項發行時可(kě)選功能。

在 .NET Core 當中,我們可(kě)以随時發布包含代碼運行所需的(de)一(yī)切元素的(de)自(zì)包含應用程序,而無需在部署目标上安裝 .NET。在某些情況下,該應用僅需要框架中的(de)一(yī)小部分即可(kě)運行,因此修剪掉不必要的(de)框架部分能夠有效降低(dī)應用程序體積。我們利用 IL linker 對應用程序的(de) IL 進行掃描,從而檢測出哪些代碼确有必要,而後對未使用的(de)框架庫進行修剪。這能夠顯著降低(dī)某些應用程序的(de)體積。一(yī)般來講,小型工具控制台類應用程序的(de)瘦身效果最為(wèi)明顯,因為(wèi)其通常使用框架中的(de)較小子(zǐ)集,且調整難度更低(dī)。

要使用 linker 工具:

将 PublishTrimmed 的(de)屬性設置為(wèi) true。

将 RuntimeIdentifier 作為(wèi)顯式參數進行發布。

以下為(wèi)相關示例:

使用以下命令進行發布:

備注:RuntimeIdentifier 可(kě)設置為(wèi)其他操作系統或者芯片類型,亦可(kě)在項目文件內(nèi)進行設置。

根據應用程序代碼的(de)實際調用情況,所發布的(de)輸出結果将包含框架庫中的(de)一(yī)個子(zǐ)集。對于最簡單的(de) helloworld 應用,linker 工具能夠将應用程序體積縮小 68 MB 到 28 MB。

在修剪之後,需要使用反射或者相關動态功能的(de)應用程序或者框架(包括 ASP .NET Core 以及 WPF)通常無法正常執行,這是因為(wèi) linker 無法識别這種動态行為(wèi),因此一(yī)般不能确定反射操作在運行時中需要的(de)框架類型。要修剪這類應用程序,大家需要告知 linker 相關代碼當中所依賴的(de)各類工具包或框架以及各種相關信息類型。請确保您在修剪之後對應用程序進行全面測試,我們也正在 .NET 5 當中對這一(yī)體驗做(zuò)出改進。

關于 IL Linker 的(de)更多細節信息,請參閱說明文檔或者訪問 mono/linker 庫。

備注:在 .NET Core 之前的(de)版本當中,ILLink Tasks 以外部 NuGet 軟件包的(de)形式提供,其中包含多種相同功能。但相關軟件包現已不再受到支持,請更新至 .NET Core 3.0 SDK 以獲取我們為(wèi)您準備的(de)全新體驗.

Linker 與 R2R 編譯器可(kě)同時作用于一(yī)款應用程序。一(yī)般來講,Linker 能夠使您的(de)應用程序體積更小,而 R2R 則能夠再次恢複其體積,并在性能上帶來顯著提升。大家可(kě)以在各種配置當中進行測試,以了解各個選項帶來的(de)具體影響。

發布單文件可(kě)執行文件

現在,大家可(kě)以利用 dotnet publish 命令發布單文件可(kě)執行文件了。這種形式的(de)單一(yī) EXE 實際上是一(yī)個自(zì)解壓可(kě)執行文件,其中以資源形式包含所有依賴項(包括本地(dì)依賴項)。在啓動時,它會将所有依賴項複制到某個臨時目錄,通過該目錄進行加載。依賴項隻需要解壓一(yī)次,後續啓動将速度極快,不再存在任何性能損失。

大家可(kě)以通過在項目文件中添加 PublishSingleFile 屬性,或者在命令行中添加新開關的(de)方式啓用這一(yī)發布選項。

要生成獨立的(de)單 EXE 應用程序,以下示例為(wèi) 64 位 Windows 系統下的(de)命令:

備注:RuntimeIdentifier 可(kě)設置為(wèi)其他操作系統或者芯片類型,亦可(kě)在項目文件內(nèi)進行設置。

若需了解更多細節信息,請參閱單文件捆綁器說明文檔。

Assembly 修剪器、提前編譯(通過 crossgen)以及單文件捆綁功能皆為(wèi) .NET Core 3.0 中提供的(de)全新選項,大家可(kě)以根據需求獨立使用或者以組合方式使用。相信一(yī)部分用戶可(kě)能喜愛通過提前編譯器提供的(de)單 exe 發布選項,而非我們在.NET Core 3.0 當中提供的(de)自(zì)解壓可(kě)執行文件方法。.NET 5 發行版當中将正式提供提前編譯器方法。

dotnet build 現在可(kě)複制依賴項

dotnet build 現在能夠在 build 操作過程當中,将應用程序中的(de) NuGet 依賴項從 NuGet 緩存複制到 build 輸出文件夾內(nèi)。在此版本之前,各依賴項僅能作為(wèi) dotnet publish 中的(de)一(yī)部分進行複制。此次變更使您能夠利用 xcopy 将 build 輸出至不同計算機當中。

除此之外,您還需要單獨發布 linking 以及 razor page publishing 等操作。

2

.NET Core 工具:本地(dì)安裝

.NET Core 工具也經過更新以支持本地(dì)安裝。這些工具比 .NET Core 2.1 版本中的(de)原有全局工具更強大。

本地(dì)安裝具有以下特性:

限制工具的(de)使用範圍。

始終使用該工具的(de)某一(yī)特定版本,該版本可(kě)能不同于全局安裝工具或者其它本地(dì)安裝工具。具體基于本地(dì)工具 manifest 文件中定義的(de)版本。

可(kě)使用 dotnet 命令啓動,例如(rú) dotnet mytool。

備注:請參閱本地(dì)工具早期預覽版說明文檔以了解更多細節信息。

.NET Core SDK 安裝程序現在将就地(dì)升級

Windows 版本的(de) .NET Core SDK MSI 安裝程序将迎來就地(dì)升級。這将減少開發者計算機及生産計算機上所需安裝的(de) SDK 數量。

此項升級策略将專門針對 .NET Core SDK 功能範圍。各功能範圍在版本号中以最後三位數字中的(de)百位體現,例如(rú) 3.0.101 與 3.0.201 代表兩個不同的(de)版本功能範圍,而 3.0.101 與 3.0.199 則處于同一(yī)版本功能範圍。

這意味着當 .NET Core SDK 3.0.101 正式發布并安裝完畢後,.NET Core SDK 3.0.100 将被從計算機中删除(如(rú)果存在)。當 .NET Core SDK 3.0.200 可(kě)用并安裝在同一(yī)台計算機上時,.NET Core SDK 3.0.101 則不會被删除。在這種情況下,系統仍将默認使用 .NET Core SDK 3.0.200,但如(rú)果将其配置為(wèi)通過 global.json 起效,則系統仍然使用 .NET Core SDK 3.0.101(或者更高(gāo)版本的(de).1xx 版本)。

這種方法與 global.json 的(de)行為(wèi)保持一(yī)緻,允許在各補丁版本之間進行前滾 ,但無法跨越 SDK 功能範圍。因此,通過 SDK 安裝程序并進行升級,可(kě)确保應用程序不會因缺少 SDK 而發生錯誤。對于已經安裝了 Visual Studio 必要 SDK 的(de)用戶,其功能範圍也将與 Visual Studio 安裝情況保持一(yī)緻。

若需了解更多細節信息,請參閱:

.NET Core 版本控制

删除.NET Core SDK 版本

.NET Core SDK 體積改進

在 .NET Core 3.0 當中,.NET Core SDK 的(de)體積明顯更小。主要原因在于,我們轉而采用出于各種目的(de)(引用 assembiles、框架、模闆等)的(de)專用“內(nèi)置包”,從而改變了我們構建 SDK 的(de)方式。在以往的(de)版本(包括 .NET Core 2.2)當中,我們一(yī)直利用 NuGet 軟件包構建 SDK,但其中包含大量并不需要的(de)構件,且對存儲空間造成嚴重浪費。

.NET Core 3.0 SDK 體積(括号中為(wèi)體積變量)

Linux 與 MacOS 版本的(de)體積變化最為(wèi)顯著,相比之下 Windows 版本的(de)改進較小,這是因為(wèi)我們在 .NET Core 3.0 當中添加了 WPF 與 Windows Forms。令人驚訝的(de)是,盡管新增了 WPF 與 Windows Forms,安裝程序的(de)體積仍然比原先小了一(yī)點。

大家也可(kě)以在 .NET Core SDK Docker 鏡像當中感受到這一(yī)瘦身效果(僅限于 x64 Debian 與 Alpine)。

大家可(kě)以在 .NET Core 3.0 SDK 體積改進文檔中了解我們如(rú)何計算這些文件的(de)大小。這裏提供詳細的(de)說明,您可(kě)以遵循同樣的(de)方法在自(zì)己的(de)環境中運行測試。

Docker 發布更新

微軟各團隊目前都在面向微軟容器注冊表(MCR)發布新的(de)容器鏡像。這一(yī)變化主要有兩大原因:

将微軟提供的(de)容器鏡像協同至多個注冊表,包括 Docker Hub 與 Red Hat。

利用微軟 Azure 作為(wèi)全球 CDN 以交付微軟提供的(de)容器鏡像。

在.NET 團隊,我們目前将所有 .NET Core 鏡像發布至 MCR。我們在 Docker Hub 上維護有自(zì)己的(de)主頁,并打算長(cháng)期保持運營。在另一(yī)方面,MCR 并不提供類似的(de)頁面,但可(kě)以通過 Docker Hub 等公共注冊表為(wèi)用戶提供與鏡像有關的(de)信息。Microsoft.dotnet 以及 microsoft.dotnet-nightly 等舊(jiù)有代碼庫鏈接現在都已經指向新的(de)地(dì)址。不過舊(jiù)有位置中的(de)各鏡像仍将存在,不會被删除。

在支持生命周期之內(nèi),我們将繼續為(wèi) .NET Core 各個版本的(de)代碼庫提供浮動标記服務。例如(rú),2.1-sdk、2.2-runtime 以及 lastest 就屬于此類浮動标記。像 2.1.2-sdk 這類包含三個數字的(de)标簽将不再提供,我們已經在版本号內(nèi)加以體現。接下來,我們将僅通過 MCR 支持 .NET Core 3.0 鏡像。

例如(rú),現在用于提取 3.0 SDK 鏡像的(de)正确标簽字符串應該為(wèi):

新的(de) MCR 字符串将由 docker pull 以及 Dockerfile FROM 語句共同使用。

感興趣的(de)朋(péng)友可(kě)以參閱微軟容器注冊表中的(de)現有 .NET Core 鏡像以了解更多細節信息。

SDK Docker 鏡像中包含 PowerShell Core

應社區的(de)要求,PowerShell Core 已經被添加至 .NET Core SDK Docker 容器鏡像當中。PowerShell Core 是一(yī)套跨平台(Windows、Linux 以及 MacOS)自(zì)動化與配置工具 / 框架,能夠與大家的(de)現有工具良好協作,并針對結構化數據(例如(rú) JSON)CSV、XML 等)、REST API 以及對象模型進行了優化。其中包含一(yī)個命令行 shell、一(yī)種相關腳本語言以及一(yī)套用于處理(lǐ) cmdlets 的(de)框架。

現在,大家可(kě)以通過以下 Docker 命令将 PowerShell Core 視(shì)為(wèi) .NET Core SDK 容器鏡像中的(de)一(yī)部分:

目前隻有兩種将 PowerShell 引入 .NET Core SDK 容器鏡像的(de)方法,具體如(rú)下:

面向任意操作系統利用 PowerShell 語法編寫 .NET Core 應用程序 Dockerfiles。

編寫能夠輕松實現容器化的(de) .NET Core 應用程序 / 庫構建邏輯。

以下為(wèi)容器化 build(存儲卷挂載)的(de) PowerShell 啓動語法示例:

為(wèi)了讓第二條示例命令正常起效,我們需要在 Linux 上确保.ps1 文件具有以下格式,并需要利用 Unix(LF)而非 Windows(CRLF)作為(wèi)行尾以執行格式化:

備注:PowerShell Core 目前已經作為(wèi).NET Core 3.0 SDK 容器鏡像的(de)一(yī)部分進行發布,而不再歸屬于 .NET Core 3.0 SDK。

紅(hóng)帽軟件支持

2015 年(nián) 4 月,我們宣布 .NET Core 将全面登陸 Red Hat Enterprise Linux。通過與紅(hóng)帽方面的(de)出色工程合作,.NET Core 1.0 于 2016 年(nián) 6 月以組件的(de)形式出現在紅(hóng)帽系列軟件當中。另外,在與紅(hóng)帽工程師們的(de)持續交流當中,我們也了解到 Linux 社區在軟件發布方面的(de)反饋與意見。

過去(qù)四年(nián)以來,紅(hóng)帽公司先後發布了多次面向 .NET Core 的(de)更新與大版本升級,包括 2.1 與 2.2 版本。在 .NET Core 2.2 版本當中,紅(hóng)帽公司将其 .NET Core 産品擴展至包括 OpenShift 在內(nèi)的(de)多個平台。而随着 RHEL 8 的(de)發布,我們也高(gāo)興地(dì)看到微軟 .NET Core 2.1 以及即将推出的(de) 3.0 版本都被納入紅(hóng)帽 Application Streams 當中。

3

總結

.NET Core 3.0 是 .NET Core 發展曆程中的(de)又一(yī)重要新版本,其中帶來了大量改進。我們建議大家盡快着手采用新的(de) .NET Core 3.0。新版本通過多種方式對 .NET Core 做(zuò)出巨大改進,例如(rú)顯著降低(dī)了 SDK 的(de)體積、極大提升對于關鍵場景(例如(rú)容器以及 Windows 桌面應用程序)的(de)支持效果。受到篇幅所限,這裏無法一(yī)一(yī)列出其它小的(de)改進,但相信随着時間的(de)推移,大家一(yī)定能夠從這些細節增強中受益。

最後,希望大家能夠在接下來的(de)使用當中與我們分享體驗與感受。希望開發者喜歡 .NET Core 3.0,我們也熱切希望根據大家的(de)喜好對産品進行打磨。

https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0/

責任編輯:中山網站建設
 【網訊網絡】國(guó)家高(gāo)新技術企業》十年(nián)專注軟件開發,網站建設,網頁設計,APP開發,小程序,微信公衆号開發,定制各類企業管理(lǐ)軟件(OA、CRM、ERP、訂單管理(lǐ)系統、進銷存管理(lǐ)軟件等)!服務熱線:0760-88610046、13924923903,http://www.wansion.net

您的(de)項目需求咨詢熱線:0760-88610046(國(guó)家高(gāo)新技術企業)

*請認真填寫需求,我們會在24小時內(nèi)與您取得聯系。