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

2019-09-30

作者丨Richard Lander   譯者丨核子可樂    策劃丨趙钰瑩

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

QQ圖片20190930112954.png

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

.NET Core 3.0 SDK 與運行時

Snap 安裝程序

Docker 鏡像

此外(wài), 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 的協同使用。.NET Core 3.0 爲 Visual Studio 2019 16.3 中(zhōng)的組成部分(fēn),開(kāi)發者可以選擇直接升級至 Visual Studio 2019 16.3,從而立刻獲取 .NET Core。

感謝所有爲 .NET Core 3.0 做出貢獻的朋友們!此次最新版本的發布源自數百位團隊成員(yuán)的努力,也包括技術社區的重大(dà)貢獻。

發行說明:

.NET Core 3.0 發行說明

.NET Core 2.2 -> 3.0 API 的區别

.NET Core 3.0 貢獻者名單

GitHub 發行版

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

1

3.0 版本,開(kāi)發者需要了解什麽?

在深入探究 .NET Core 3.0 中(zhōng)的全部新功能之前,我(wǒ)們首先需要強調幾項關鍵性的改進與指導内容。以下(xià)是整理出的要點清單:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

平台支持

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

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 内核 4.14 或者更新版本。例如,Ubuntu 18.04 能夠滿足這一(yī)條件,但 16.04 版本無法支持。

WPF 與 Windows Forms

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

下(xià)圖所示爲一(yī)款 .NET Core Windows Forms 應用:

QQ圖片20190930113120.png


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

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

下(xià)圖所示爲顯示在新設計器當中(zhōng)的 WPF 應用:

微信圖片_20190930113238.png


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

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

您也可以利用同樣的流程創建 WPF 應用:

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

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

Windows 原生(shēng)互操作

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

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

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

可空引用類型

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

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

某項引用可以爲空。當變量可以爲空時,編譯器會強制執行規則以确保您已經對所引用的變量是否爲空做出檢查。

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

接口成員(yuán)的默認實現

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

在 C# 8.0 當中(zhōng),大(dà)家可以爲某一(yī)接口成員(yuán)提供主體(tǐ)。結果就是,如果實現該接口的類沒有實現該成員(yuán)(可能是因爲編寫代碼時還不存在該成員(yuán)),那麽調用代碼将隻能獲得默認的實現效果。

在本示例當中(zhōng),ConsoleLogger 類并不需要實現對 ILogger 中(zhōng)的 Log(Exception) 重載,因爲其是通過默認實現進行聲明的。現在,隻要爲現有實現成員(yuán)提供默認實現,您就可以随時向現有接口添加新的成員(yuán)。

異步流

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

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

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

索引與範圍

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

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

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

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

Switch 表達式

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

terser 語法

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

與模式匹配全面集成

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

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

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

大(dà)家也可以更進一(yī)步依賴元組解構與參數位置,具體(tǐ)如下(xià)所示:

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

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

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

速度更快的 JSON API

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

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

下(xià)面,讓我(wǒ)們分(fēn)層對這一(yī)新的 API 家族做出闡述。

Utf8JsonReader

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

Utf8JsonWriter

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

JsonDocument

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

JSON 序列化器

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

引入全新 SqlClient

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

ARM 與物(wù)聯網支持

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

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

此功能屬于以下(xià)軟件包中(zhōng)的組成部分(fēn):

System.Device.Gpio

Iot.Device.Bindings

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

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

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

我(wǒ)們發布了一(yī)項名爲 RollForward 的新屬性,該屬性能夠接受以下(xià)值:

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

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

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

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

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

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

Docker 與 cgroup 限制

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

Docker 資(zī)源限制功能構建在 cgroup 基礎之上,而 cgroup 又(yòu)是一(yī)項 Linux 内核功能。從運行時的角度來看,我(wǒ)們需要以 cgroup 基元爲目标。

大(dà)家可以利用 docker run -m 參數來限制容器的可用内存,如下(xià)所示,此示例用于創建一(yī)個基于 Alpine 且内存容量爲 4 MB 的容(而後輸出内存限制):

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

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

默認情況下(xià)降低 GC 堆大(dà)小(xiǎo)

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

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

當然,我(wǒ)們在 ASP.NET 基準測試中(zhōng)觀察到的内存節約效果,可能代表 / 不代表您的實際體(tǐ)驗。我(wǒ)們希望聽(tīng)到更多朋友在實際應用程序内存使用量方面觀察到的結果。

改善對多處理器設備的支持能力

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

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

GCLarge Page 支持

Large Pages 或者叫 Huge Pages 是一(yī)項功能,操作系統可利用其構建起大(dà)于原生(shēng)頁面大(dà)小(xiǎo)(通常爲 4K)的内存區域,從而提高調用這些大(dà)頁面的應用程序的性能表現。

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

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

.NET Core 版本 API

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

現在,大(dà)家可以訪問以下(xià)版本信息:

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

添加了新的 Perf Counters:

GC 中(zhōng)的時間百分(fēn)比

Gen 0 堆大(dà)小(xiǎo)

Gen 1 堆大(dà)小(xiǎo)

Gen 2 堆大(dà)小(xiǎo)

LOH 堆大(dà)小(xiǎo)

分(fēn)配率

加載組件數量

ThreadPool 線程數量

鎖定争用率

ThreadPool 工(gōng)作條目隊列

ThreadPool 已完成工(gōng)作項比例

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

HTTP/2 支持

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

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

分(fēn)層編譯

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

IEEE 浮點改進

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

解析與格式化修複:

正确解析并舍入任何長度的輸入。

正确解析并格式化負零。

通過進行不區分(fēn)大(dà)小(xiǎo)寫的檢查,并在适用時允許使用可選前置 + 以正确解析無限與 NaN。

新的 Math API:

BitIncrement/BitDecrement ——對應于 nextUp 與 nextDown IEEE 運算。二者分(fēn)别返回大(dà)于或者小(xiǎo)于輸入内容的最小(xiǎo)浮點數。例如,Math.BitIncrement(0.0)将返回 double.Epsilon。

MaxMagnitude/MinMagnitude——對應于 maxNumMag 與 minNumMag IEEE 運算,二者分(fēn)别返回大(dà)于或者小(xiǎo)于輸入内容的值。例如,Math.MaxMagnitude(2.0 -3.0) 将返回 -3.0。

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

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

Log2——對應于 log2 IEEE 運算,返回以 2 爲底的對數,且舍入誤差最小(xiǎo)。

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

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

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

.NET 平台相關改進

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

以下(xià) CoreCLR PRs 通過實現或者使用的方式展示了一(yī)部分(fēn)内部函數:

實現簡單 SSE2 硬件内部函數

實現 SSE 硬件内部函數

Arm64 Base 硬件内部函數

面向 LocateFound使用 TZCNT 與 LZCNT

現可在 Linux 上支持 TLS 1.3 與 OpenSSL 1.1.1

.NET Core 現在能夠利用 OpenSSL 1.1.1 中(zhōng)的 TLS 1.3 支持能力。TLS 1.3 能夠爲 OpenSSL 團隊提供多項優勢:

通過減少客戶端與服務器間的往返次數縮短連接時長。

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

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

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

加密

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

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

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

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

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

支持新的日本年号(令和)

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

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

Assembly Load Context 改進

關于 AssemblyLoadContext 的改進:

實現上下(xià)文命名

添加 ALC 枚舉功能

對 ALC 内程序集進行枚舉的功能

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

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

Assembly 可卸載性

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

我(wǒ)們希望這項新功能被用于以下(xià)場景:

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

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

加載程序集以進行自我(wǒ)檢查(例如 ReflectionOnlyLoad),但在大(dà)多數情況下(xià) MetadataLoadContext 仍然是更好的選擇。

利用 MetadataLoadContext 讀取 Assembly 元數據

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

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

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

Native Hosting 示例

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

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

其他 API 改進

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

下(xià)面來看其它最新改進:

Brotli 内置 HttpClient 支持能力

ThreadPool.UnsafeQueueWorkItem(IThreadPoolWorkItem)

Unsafe.Unbox

CancellationToken.Unregister

複雜(zá)算術運算符

Socket APIs for TCP 仍然有效

StringBuilder.GetChunks

IPEndPoint 解析

RandomNumberGenerator.GetInt32

System.Buffers.SequenceReader

默認情況下(xià),應用程序現在具有原生(shēng)可執行文件

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

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

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

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

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

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

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

要啓用 R2R 編譯:

将 PublishReadyToRun 屬性設置爲 true。

使用 RuntimeIdentifie 顯式參數發布。

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

以下(xià)爲具體(tǐ)示例:

使用以下(xià)命令進行發布:

備注:RuntimeIdentifier 可設置爲其他操作系統或者芯片類型,亦可在項目文件内進行設置。

Assembly Linking

.NET core 3.0 SDK 附帶一(yī)款工(gōng)具,可通過分(fēn)析 IL 與修剪未使用的 assemblies 以降低應用程序的體(tǐ)積。這是 .NET Core 3.0 中(zhōng)的另一(yī)項發行時可選功能。

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

要使用 linker 工(gōng)具:

将 PublishTrimmed 的屬性設置爲 true。

将 RuntimeIdentifier 作爲顯式參數進行發布。

以下(xià)爲相關示例:

使用以下(xià)命令進行發布:

備注:RuntimeIdentifier 可設置爲其他操作系統或者芯片類型,亦可在項目文件内進行設置。

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

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

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

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

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

發布單文件可執行文件

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

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

要生(shēng)成獨立的單 EXE 應用程序,以下(xià)示例爲 64 位 Windows 系統下(xià)的命令:

備注:RuntimeIdentifier 可設置爲其他操作系統或者芯片類型,亦可在項目文件内進行設置。

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

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

dotnet build 現在可複制依賴項

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

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

2

.NET Core 工(gōng)具:本地安裝

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

本地安裝具有以下(xià)特性:

限制工(gōng)具的使用範圍。

始終使用該工(gōng)具的某一(yī)特定版本,該版本可能不同于全局安裝工(gōng)具或者其它本地安裝工(gōng)具。具體(tǐ)基于本地工(gōng)具 manifest 文件中(zhōng)定義的版本。

可使用 dotnet 命令啓動,例如 dotnet mytool。

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

.NET Core SDK 安裝程序現在将就地升級

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

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

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

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

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

.NET Core 版本控制

删除.NET Core SDK 版本

.NET Core SDK 體(tǐ)積改進

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

.NET Core 3.0 SDK 體(tǐ)積(括号中(zhōng)爲體(tǐ)積變量)

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

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

大(dà)家可以在 .NET Core 3.0 SDK 體(tǐ)積改進文檔中(zhōng)了解我(wǒ)們如何計算這些文件的大(dà)小(xiǎo)。這裏提供詳細的說明,您可以遵循同樣的方法在自己的環境中(zhōng)運行測試。

Docker 發布更新

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

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

利用微軟 Azure 作爲全球 CDN 以交付微軟提供的容器鏡像。

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

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

例如,現在用于提取 3.0 SDK 鏡像的正确标簽字符串應該爲:

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

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

SDK Docker 鏡像中(zhōng)包含 PowerShell Core

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

現在,大(dà)家可以通過以下(xià) Docker 命令将 PowerShell Core 視爲 .NET Core SDK 容器鏡像中(zhōng)的一(yī)部分(fēn):

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

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

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

以下(xià)爲容器化 build(存儲卷挂載)的 PowerShell 啓動語法示例:

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

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

紅帽軟件支持

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

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

3

總結

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

最後,希望大(dà)家能夠在接下(xià)來的使用當中(zhōng)與我(wǒ)們分(fēn)享體(tǐ)驗與感受。希望開(kāi)發者喜歡 .NET Core 3.0,我(wǒ)們也熱切希望根據大(dà)家的喜好對産品進行打磨。

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

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

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

*請認真填寫需求,我(wǒ)們會在24小(xiǎo)時内與您取得聯系。