2019-09-30
作者丨Richard Lander 譯者丨核子可(kě)樂(yuè) 策劃丨趙钰瑩
近日,.NET Core 3.0 正式發布。此次新版本包含一系列重要改進,添加了(le) Windows Forms 與 WPF、添加新的(de) JSON API、對(duì) ARM64 的(de)支持能力以及全面提高(gāo)的(de)性能水(shuǐ)平等。此外,C# 8 也(yě)是此次新版本的(de)重要組成部分(fēn),其中包含可(kě)空、異步流以及更多(duō)模式。F# 4.7 則專注于放寬語法限制,并專門匹配 .NET Standard 2.0。開發者現在可(kě)以立即将原有項目更新爲 .NET Core 3.0,此次新版本與原有版本兼容,大(dà)家可(kě)以放心體驗。
根據微軟博客的(de)介紹,開發者可(kě)以面向 Windows、MacOS 以及 Linux 等系統平台下(xià)載 .NET Core 3.0 :
.NET Core 3.0 SDK 與運行時(shí)
Snap 安裝程序
Docker 鏡像
此外, ASP .NET Core 3.0 與 EF Core 3.0 也(yě)已經一同發布。Visual Studio 2019 16.3 與 Visual Studio for Mac 8.3 亦同時(shí)發布,且需要更新才能确保 .NET Core 3.0 與 Visual Studio 的(de)協同使用(yòng)。.NET Core 3.0 爲 Visual Studio 2019 16.3 中的(de)組成部分(fēn),開發者可(kě)以選擇直接升級至 Visual Studio 2019 16.3,從而立刻獲取 .NET Core。
感謝所有爲 .NET Core 3.0 做(zuò)出貢獻的(de)朋友們!此次最新版本的(de)發布源自數百位團隊成員(yuán)的(de)努力,也(yě)包括技術社區(qū)的(de)重大(dà)貢獻。
發行說明(míng):
.NET Core 3.0 發行說明(míng)
.NET Core 2.2 -> 3.0 API 的(de)區(qū)别
.NET Core 3.0 貢獻者名單
GitHub 發行版
關于 .NET Core 3.0 的(de) GitHub 問題解答(dá)
1
3.0 版本,開發者需要了(le)解什(shén)麽?
在深入探究 .NET Core 3.0 中的(de)全部新功能之前,我們首先需要強調幾項關鍵性的(de)改進與指導内容。以下(xià)是整理(lǐ)出的(de)要點清單:
.NET Core 3.0 已經在 dot.net 以及 Bing.com 上托管了(le)幾個(gè)月(yuè),通(tōng)過了(le)一系列嚴苛的(de)測試。衆多(duō)其他(tā)微軟團隊也(yě)将很快(kuài)在生産流程當中通(tōng)過 .NET Core 3.0 部署一系列大(dà)型工作負載。
多(duō)種組件的(de)性能得(de)到顯著提升,感興趣的(de)朋友可(kě)以點擊此處參閱 .NET Core 3.0 的(de)性能改進說明(míng)。
C# 8 加入了(le)異步流、範圍 / 索引、更多(duō)模式以及可(kě)爲空的(de)引用(yòng)類型。可(kě)爲空意味著(zhe)可(kě)以直接發現那些導緻 NullReferenceException 問題的(de)代碼缺陷。框架庫的(de)最底層注釋也(yě)已添加完成,以幫助了(le)解何時(shí)爲 Null。
F# 4.7 緻力于通(tōng)過隐式 yield 表達式及相關語法降低某些操作的(de)實現難度。其中還(hái)包含對(duì) LangVersion 的(de)支持,提供 nameof 并可(kě)以預覽形式打開靜态類。F# Core 核心庫現在還(hái)與 .NET Standard 2.0 相匹配。您可(kě)以點擊此處參閱 F# 4.7 發布公告中的(de)細節信息。
.NET Standard 2.1 增加了(le)可(kě)與 .NET Core 以及 Xamarin 共同使用(yòng)的(de)代碼類型集。.NET Standar 2.1 當中包含 .NET Core 2.1 以及之後版本中的(de)所有類型。
Windows 桌面應用(yòng)現已面向 Windows Forms 與 WPF(開源)得(de)到 .NET Core 支持。其中,WPF 設計器爲 Visual Studio 2019 16.3 版本中的(de)組成部分(fēn)。Windows Forms 設計器仍處于預覽狀态,并可(kě)通(tōng)過 VSIX 下(xià)載的(de)形式獲取。
.NET Core 應用(yòng)現在默認具備可(kě)執行文件。在以往的(de)發行版中,應用(yòng)需要通(tōng)過 dotnet 命令方啓動,例如 dotnet myapp.dll。現在,可(kě)以通(tōng)過應用(yòng)特定可(kě)執行文件實現應用(yòng)啓動,例如 myapp 或者./myapp,具體視使用(yòng)的(de)操作系統而定。
高(gāo)性能 JSON API 加入新版本,适用(yòng)于 reader/writer、對(duì)象模型以及序列化(huà)場(chǎng)景等。這(zhè)些 API 在 Span 基礎之上重新構建而成,且在底層使用(yòng) UTF8(而非 string 等 UTF16)。這(zhè)些 API 能夠将分(fēn)配需求控制在最低程度,從而提高(gāo)性能、減少垃圾收集器的(de)工作量。具體請參閱.NET Core 3.0 中的(de) JSON 未來(lái)發展說明(míng)。
默認情況下(xià),垃圾收集器的(de)内存占用(yòng)量得(de)到了(le)顯著削減。對(duì)于将衆多(duō)應用(yòng)程序托管在同一服務器之上的(de)使用(yòng)場(chǎng)景,這(zhè)項改進可(kě)謂意義重大(dà)。垃圾收集器本身也(yě)得(de)到了(le)更新,能夠利用(yòng) 64 核及以上設備的(de)大(dà)量計算(suàn)核心。
.NET Core 已針對(duì) Docker 進行了(le)增強,以使 .NET 應用(yòng)程序能夠在容器中以可(kě)預測的(de)方式高(gāo)效運作。在容器配置中的(de)内存或 CPU 資源有限時(shí),目前的(de)垃圾收集器與線程池更新結果也(yě)能帶來(lái)更好的(de)運作效果。.NET Core docker 鏡像也(yě)變得(de)更小,其中 SDK 鏡像的(de)瘦身效果尤其明(míng)顯。
Raspberry Pi 與 ARM 芯片現已得(de)到支持,可(kě)配合遠(yuǎn)程 Visual Studio 調試程序等工具實現物(wù)聯網開發。開發者可(kě)部署應用(yòng)以監聽(tīng)各傳感器,同時(shí)将消息或者圖像輸出至顯示器上,整個(gè)過程皆可(kě)通(tōng)過新的(de) GPIO API 實現。ASP.NET 則可(kě)用(yòng)于将數據公布于 API 或者以站點的(de)形式對(duì)物(wù)網設備進行配置。
.NET Core 3.0 即爲“當前”版本,我們計劃在 2019 年 11 月(yuè)推出下(xià)一代 .NET Core 3.1 版本。.NET Core 3.1 将爲長(cháng)期支持(LTS)版本(周期至少爲 3 年)。我們建議(yì)您首先采用(yòng) .NET Core 3.0,而後更新至 3.1 版,升級過程将非常輕松。
.NET Core 2.2 将于今年 12 月(yuè) 23 日停止服務,具體情況請參閱 .NET Core 支持策略。
.NET Core 3.0 将通(tōng)過 RHEL 8 的(de)紅帽 Applicaltion Streams 交付,這(zhè)也(yě)是我們與紅帽公司多(duō)年合作的(de)最新成果。
對(duì)于希望在 Windows 上使用(yòng) .NET Core 3.0 的(de)用(yòng)戶,将必須升級至 Visual Studio 2019 16.3。
對(duì)于希望在 Mac 上使用(yòng) .NET Core 3.0 的(de)用(yòng)戶,将必須升級至 Visual Studio for Mac 8.3。
Visual Studio Code 用(yòng)戶應始終使用(yòng)最新版本的(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 将在以下(xià)操作系統平台上得(de)到支持:
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 應用(yòng)隻适用(yòng)于 Windows 操作系統。
芯片支持情況:
x64,Windows、macOS 以及 Linux
x86,Windows
ARM32,Windows 與 Linux
ARM64,Linux (kernel 4.14+)
備注:請确保 .NET Core 3.0 ARM64 部署方案采用(yòng) Linux 内核 4.14 或者更新版本。例如,Ubuntu 18.04 能夠滿足這(zhè)一條件,但 16.04 版本無法支持。
WPF 與 Windows Forms
開發者可(kě)以在 Windows 系統上利用(yòng) .NET Core 3 構建 WPF 與 Windows Forms 應用(yòng)從項目起步之初,我們就制定了(le)強大(dà)的(de)兼容性目标,旨在保證桌面應用(yòng)程序能夠從 .NET Framework 輕松遷移至 .NET Core 當中。我們已經收到衆多(duō)開發人(rén)員(yuán)的(de)反饋,了(le)解到他(tā)們已經成功将自己的(de)應用(yòng)遷移至 .NET Core 3.0,且整個(gè)流程非常輕松便捷。從了(le)盡可(kě)能降低對(duì)開發人(rén)員(yuán)的(de)影(yǐng)響,WPF 以及 Windows Forms 沒有受到任何影(yǐng)響,其仍可(kě)在 .NET Core 上正常運行。事實上,項目本身進行了(le)重大(dà)調整,但我們認爲不對(duì)用(yòng)戶造成影(yǐng)響才是最好的(de)調整方式。
下(xià)圖所示爲一款 .NET Core Windows Forms 應用(yòng):
Visual Studio 2019 16.3 已經支持創建能夠匹配 .NET Core 的(de) WPF 應用(yòng)。其中包括新的(de)模闆、經過更新的(de) XAML 設計器以及 XMAL Hot Reload。該設計器類似于現有 XAML 設計器(能夠匹配.NET Framework),但二者在體驗上仍然略有不同。
從技術層面來(lái)看,最大(dà)的(de)區(qū)别在于面向 .NET Core 的(de)設計器采用(yòng)新的(de)接口進程(wpfsurface.exe)以僅運行針對(duì) .NET Core 版本的(de)運行時(shí)代碼。以往,.NET Framework WPF 設計器進程(xdesproc.exe)本身即爲承載設計器的(de) WPF .NET Framework 進程;由于運行時(shí)不兼容,我們無法使用(yòng) WPF .NET Framework 進程(在本示例爲中 Visual Studio)将兩個(gè)版本的(de) .NET(即 .NET Framework 與 .NET Core)加載至同一進程當中。這(zhè)意味著(zhe)設計器在一定程度上(例如設計器擴展)無法以同樣的(de)方式運作。如果正在編寫設計器擴展,我們建議(yì)認真閱讀 XAML 設計器擴展遷移文檔。
下(xià)圖所示爲顯示在新設計器當中的(de) WPF 應用(yòng):
Windows Forms 設計器目前仍處于預覽狀态,可(kě)以單獨進行下(xià)載。其将在後續更高(gāo)版本内被添加至 Visual Studio 當中。該設計器的(de)當前預算(suàn)版包含對(duì)最常用(yòng)控件以及底層功能的(de)支持。我們将通(tōng)過每月(yuè)更新不斷對(duì)該設計器做(zuò)出更新。我們目前不建議(yì)大(dà)家将自己的(de) Windows Forms 應用(yòng)程序移植至 .NET Core,特别是在高(gāo)度依賴設計器的(de)情況下(xià)。希望開發者體驗目前的(de)設計器預覽版,并積極向我們反饋問題。
另外,大(dà)家也(yě)可(kě)以利用(yòng) .NET CLI 通(tōng)過命令行進行桌面應用(yòng)程序的(de)創建與構建。例如,您可(kě)以通(tōng)過以下(xià)命令快(kuài)速創建一個(gè)新的(de) Windows Forms 應用(yòng):
您也(yě)可(kě)以利用(yòng)同樣的(de)流程創建 WPF 應用(yòng):
早在 2018 年 12 月(yuè),我們就将 Windows Forms 與 WPF 轉化(huà)爲開源項目。很高(gāo)興看到,目前技術社區(qū)以及 Windows Forms 及 WPF 團隊正共同努力以改進這(zhè)兩套 UI 框架。在 WPF 方面,我們最初在 GitHub 庫中隻擁有少量代碼,但目前幾乎全部 WPF 代碼都已經發布至 GitHub。随著(zhe)時(shí)間的(de)推移,未來(lái)還(hái)将有更多(duō)組件出現。與其他(tā) .NET Core 項目一樣,這(zhè)些新的(de)庫将成爲 .NET Foundation 的(de)一部分(fēn),并遵循 MIT 開源許可(kě)。
System.Windows.Forms.DataVisualization 軟件包(包含圖表控件)目前也(yě)适用(yòng)于新的(de) .NET Core 版本。大(dà)家現在可(kě)以将這(zhè)些控制添加到您的(de) .NET Core WinForms 應用(yòng)程序當中。該圖表控件的(de)源代碼可(kě)從 Github 上的(de) dotnet/winforms-datavisualization 處獲取。控件本身已經進行了(le)調整,以簡化(huà)面向 .NET Core 3 的(de)移植過程,但我們并不打算(suàn)對(duì)其做(zuò)出大(dà)規模更新。
Windows 原生互操作
Windows 以常規 API、COM 以及 WinRT 的(de)形式提供豐富的(de)原生 API。我們也(yě)從 .NET Core 1.0 時(shí)代起即提供對(duì) P/Invoke 的(de)支持;在此次 .NET Core 3.0 當中,我們進一步添加了(le) CoCreate COM API、主動 WinRT API,以及将托管代碼以 COM 組件形式處理(lǐ)等功能。很多(duō)開發人(rén)員(yuán)都就這(zhè)些功能向我們提出申請,我們相信其正式推出也(yě)将給大(dà)家的(de)日常工作帶來(lái)巨大(dà)便利。
去年下(xià)半年,我們宣布已經設法通(tōng)過 .NET Core 實現了(le) Excel 自動化(huà)。那絕對(duì)是個(gè)有趣的(de)時(shí)刻。在底層,我們的(de)展示利用(yòng)到 COM 互操作機制,例如 NOPIA、對(duì)象等效性以及自定義編組器等等。現在,您可(kě)以在擴展示例當中親自體驗多(duō)種相關演示方案。
目前,.NET Core 3.0 隻部分(fēn)支持托管 C++ 與 WinRT 互操作,完整的(de)支持能力将在 .NET Core 3.1 當中推出。
可(kě)空引用(yòng)類型
C# 8.0 當中引入了(le)可(kě)空與不可(kě)空兩種新的(de)引用(yòng)類型,這(zhè)意味著(zhe)用(yòng)戶可(kě)以對(duì)引用(yòng)類型變量的(de)屬性做(zuò)出重要聲明(míng):
某項引用(yòng)不應爲空。當變量不應爲空時(shí),則編譯器會強制執行規則以确保安全地撤銷針對(duì)空變量的(de)引用(yòng),而無需預先檢查引用(yòng)目标是否爲空。
某項引用(yòng)可(kě)以爲空。當變量可(kě)以爲空時(shí),編譯器會強制執行規則以确保您已經對(duì)所引用(yòng)的(de)變量是否爲空做(zuò)出檢查。
相較于無法從引用(yòng)變量的(de)變量聲明(míng)當中确定設計意圖的(de)早期 C# 版本,此次發布的(de)新功能具有明(míng)顯的(de)優勢。通(tōng)過添加可(kě)空這(zhè)一全新引用(yòng)類型,您将能夠更明(míng)确地聲明(míng)自己的(de)設計意圖,而編譯器則可(kě)以幫助您正确地完成這(zhè)一目标并及時(shí)發現代碼中的(de)錯誤。
接口成員(yuán)的(de)默認實現
目前,一旦接口發布完畢,您将無法對(duì)其做(zuò)出任何變更:換言之,要向其中添加新成員(yuán),我們就必然會對(duì)現有界面的(de)實現成員(yuán)造成破壞。
在 C# 8.0 當中,大(dà)家可(kě)以爲某一接口成員(yuán)提供主體。結果就是,如果實現該接口的(de)類沒有實現該成員(yuán)(可(kě)能是因爲編寫代碼時(shí)還(hái)不存在該成員(yuán)),那麽調用(yòng)代碼将隻能獲得(de)默認的(de)實現效果。
在本示例當中,ConsoleLogger 類并不需要實現對(duì) ILogger 中的(de) Log(Exception) 重載,因爲其是通(tōng)過默認實現進行聲明(míng)的(de)。現在,隻要爲現有實現成員(yuán)提供默認實現,您就可(kě)以随時(shí)向現有接口添加新的(de)成員(yuán)。
異步流
現在,您可(kě)以利用(yòng) IAsyncEnumerable 對(duì)異步數據流進行 foreach。這(zhè)一新的(de)接口滿足了(le)衆多(duō)開發人(rén)員(yuán)的(de)長(cháng)久需求,也(yě)就是 IEnumerable 的(de)異步版本。該語言允許大(dà)家對(duì)任務進行 await foreach 以使用(yòng)其元素。在産生方面,您的(de) yield return 條目可(kě)能會産生異步流。雖然聽(tīng)起來(lái)似乎比較複雜(zá),但其實際上将在實踐當中顯著簡化(huà)操作。
以下(xià)示例展示了(le)異步流的(de)産生與使用(yòng)情況。其中的(de) foreach 聲明(míng)爲異步,其本身會利用(yòng) yield return 爲調用(yòng)程序産生一條異步流。這(zhè)種利用(yòng) yield return 的(de)模式亦是我們推出的(de)異步流标準生産方式。
除了(le)能夠實現 await foreach 之外,大(dà)家也(yě)可(kě)以創建出異步叠代器,例如一個(gè)能夠返回 IAsyncEnumerable/IAsyncEnumerator 并在其中同時(shí)實現 await 與 yield return 的(de)叠代器。對(duì)于需要處理(lǐ)的(de)對(duì)象,您也(yě)可(kě)以使用(yòng)能夠實現 Stream 以及 Timer 等多(duō)種框架類型的(de) IAsyncDisposable。
索引與範圍
我們還(hái)創建了(le)新的(de)語法與類型,可(kě)用(yòng)于描述索引器、數組元素訪問或者可(kě)以直接進行數據訪問的(de)任何其他(tā)類型。其中包括對(duì)單一值(索引的(de)通(tōng)常定義)或者兩個(gè)值(描述範圍)的(de)支持。
Index 是一種用(yòng)于描述數組索引的(de)新類型。您可(kě)以從通(tōng)過 int 從零開始對(duì) Index 進行計數,也(yě)可(kě)以使用(yòng) ^ 前綴運算(suàn)符創建索引。在以下(xià)示例中,我們可(kě)以同時(shí)觀察到這(zhè)兩種情況:
Range 的(de)概念基本相同,其由兩個(gè) Index 值構成,其一代表開始、其二代表結束,且可(kě)以用(yòng) x…y 的(de)範圍表達式編寫。接下(xià)來(lái),大(dà)家即可(kě)使用(yòng) Range 索引以生成底層數據的(de)一個(gè)切片,具體如下(xià)所示:
使用(yòng)聲明(míng)很多(duō)朋友可(kě)能已經厭倦了(le)使用(yòng)那些要求縮進代碼的(de)語句,對(duì)吧?沒問題,現在不會了(le)。您可(kě)以按以下(xià)形式編寫代碼,該代碼将在當前語句塊的(de)作用(yòng)域末尾添加 using 聲明(míng),而後将對(duì)象放置在其末尾。
Switch 表達式
幾乎每一位 C# 用(yòng)戶都非常喜歡 switch 語句的(de)概念,但卻不太喜歡它的(de)語法。C# 8 引入了(le) switch 表達式,該表達式可(kě)實現以下(xià)功能:
terser 語法
由于其屬于表達式,所以會返回一個(gè)值
與模式匹配全面集成
Switch 表達式中的(de)關鍵字爲“infix”,意味著(zhe)該關鍵字位于測試值(在第一個(gè)示例中爲 0)與示例列表之間,這(zhè)種形式與 Lambda 表達式非常相似。
第一個(gè)示例對(duì)各方法使用(yòng)了(le) Lambda 語法,該語法能夠與 switch 表達式良好集成,但并非必需。
在此示例中,共有兩種模式在發揮作用(yòng)。首先,0 會與 Point 類型模式匹配,而後再與内的(de)屬性模式匹配。_ 用(yòng)于描述丢棄模式,其與 switch 語句的(de)默認模式想再。
大(dà)家也(yě)可(kě)以更進一步依賴元組解構與參數位置,具體如下(xià)所示:
在本示例中,大(dà)家可(kě)以看到我們并不需要爲每一種情況定義變量或者顯式類型。相反,編譯器可(kě)以将當前正在測試的(de)元組與已經定義的(de)元組進行匹配。
所有這(zhè)些模式,使得(de)我們能夠編寫出意圖更加明(míng)确的(de)聲明(míng)性代碼,而非單純執行測試的(de)過程代碼。編譯器能夠負責實現無聊的(de)過程代碼,并保證其始終得(de)到正确執行。
當然,在某些情況下(xià),switch 語句的(de)實際效果可(kě)能仍然優于新的(de) switch 表達式與模式中的(de)語法形式。
速度更快(kuài)的(de) JSON API
.NET Core 3.0 當中包含一個(gè)新的(de) JSON API 家族,其用(yòng)于實現 reader/writer 場(chǎng)景、利用(yòng)文檔對(duì)象模型(DOM)實現随機訪問外加一個(gè)序列化(huà)程序。大(dà)家可(kě)能已經非常熟悉如何使用(yòng) Json.NET 。新的(de) API 旨在滿足大(dà)多(duō)數同類場(chǎng)景需求,但内存需求更低、執行速度更快(kuài)。
簡而言之,我們希望構建一個(gè)新的(de) JSON API,從而充分(fēn)利用(yòng).NET Core 中的(de)所有全新性能優勢,并以此爲基礎全面提升性能水(shuǐ)平。很明(míng)顯,我們不可(kě)能在保持現有代碼庫(例如 Jason.NET )兼容性的(de)同時(shí)達成這(zhè)一目标。
下(xià)面,讓我們分(fēn)層對(duì)這(zhè)一新的(de) API 家族做(zuò)出闡述。
Utf8JsonReader
System.Text.Json.Utf8JsonReader 是種面向面向 UTF-8 編碼 JSON 文本的(de)高(gāo)性能、低分(fēn)配、純轉發讀取器,負責從 ReadOnlySpan 當中讀取内容。Utf8JsonReader 是一種基礎的(de)低級類型,我們可(kě)以利用(yòng)它構建自定義解析器與解串器。利用(yòng)新的(de) Utf8JasonReader,對(duì) JSON 負載的(de)讀取速度将可(kě)達到以往 Json.NET 中讀取速度的(de)兩倍。另外,除非大(dà)家需要将 JSON 令牌實現爲(UTF16)字符串,否則其不會進行分(fēn)配。
Utf8JsonWriter
System.Text.Json.Utf8JsonWriter 提供一種高(gāo)性能、非緩存、純轉發方式,可(kě)用(yòng)于将 String、Int32 以及 DateTime 等常規.NET 類型寫入爲 UTF-8 編碼 JSON 文本。與 reader 類似,writer 是一種基礎低級類型,開發人(rén)員(yuán)可(kě)以利用(yòng)它構建自定義序列化(huà)程序。使用(yòng)新的(de) Utf8JasonWriter,JSON 負載的(de)編寫速度将比 Json.NET 寫入器高(gāo) 30% 到 80%,且不進行分(fēn)配。
JsonDocument
System.Text.Json.JsonDocument 能夠對(duì) JSON 數據進行解析,并建立隻讀文檔對(duì)象模型(DOM)功能,用(yòng)以查詢該對(duì)象以支持随機訪問與枚舉。其建立在 Utf8JasonReader 基礎之上,組成數據的(de) JSON 元素可(kě)以通(tōng)過由 JsonDocument 類型(被稱爲 RootElement 屬性)公開的(de) JsonElement 類型進行訪問。JsonElement 當中包含 JSON 數組與對(duì)象枚舉器,外加用(yòng)于将 JSON 文本轉換爲常見.NET 類型的(de) API。利用(yòng) JsonDocument,對(duì)常規 JSON 負載進行解析并訪問其中各成員(yuán)的(de)速度,一般可(kě)以達到以往 Json.NET 的(de) 2 到 3 倍;而且由于數據本身大(dà)小合理(lǐ)(小于 1 MB),因此幾乎不需要進行數據分(fēn)配。
JSON 序列化(huà)器
System.Text.Json.JsonSerializer 層位于高(gāo)性能 Utf8JsonReader 與 Utf8JsonWriter 之上。其負責對(duì)來(lái)自 JSON 的(de)對(duì)象進行反序列化(huà),并對(duì)指向 JSON 的(de)對(duì)象進行序列化(huà)。内存分(fēn)配得(de)到嚴格控制,同時(shí)支持利用(yòng) Stream 以異步方式進行 JSON 讀取與寫入。
引入全新 SqlClient
SqlClient 是一款數據提供程序,您可(kě)以利用(yòng)它直接利用(yòng) ADO .NET API 訪問微軟 SQL Server 以及 Azure SQL Database 等。SqlClient 已經正式發布,并通(tōng)過 Microsoft.Data.SqlClient NuGet 工具包進行更新,且同時(shí)支持 .NET Freamework 與 .Net Core 應用(yòng)程序。通(tōng)過使用(yòng) NuGet,SQL 團隊将能夠更輕松地爲 Freamework 與 .Net Core 用(yòng)戶提供更新。
ARM 與物(wù)聯網支持
我們在本次發行版當中實現了(le)對(duì) Linux ARM64 的(de)支持,這(zhè)也(yě)是對(duì)此前 .NET Core 2.1 與 2.2 版本當中面向 Linux 與 Windows 提供 ARM32 支持能力的(de)延續。雖然某些物(wù)聯網工作負載能夠發揮我們現有 x64 功能提供的(de)優勢,但仍有不少用(yòng)戶強烈要求發布 ARM 支持功能。現在這(zhè)一功能已經落實到位,我們也(yě)在與計劃進行大(dà)規模部署的(de)客戶開展廣泛合作。
不少利用(yòng).NET 的(de)物(wù)聯網部署場(chǎng)景涉及邊緣設備,且完全面向網絡。其他(tā)一些場(chǎng)景則要求對(duì)硬件進行直接訪問。在本次發行版中,我們添加了(le)新的(de)功能以在 Linux 上使用(yòng)串行端口,同時(shí)可(kě)利用(yòng) Raspberry Pi 等設備上的(de)數字引腳功能。該引腳使用(yòng)多(duō)項協議(yì)。我們還(hái)添加了(le)對(duì) GPIO、PWM、I2C 以及 SPI 的(de)支持,以支持讀取傳感器數據、以無線方式交互并将文本與圖像輸出至顯示器等功能。
此功能屬于以下(xià)軟件包中的(de)組成部分(fēn):
System.Device.Gpio
Iot.Device.Bindings
作爲 GPIO(及其他(tā)同類協議(yì))支持的(de)一部分(fēn),我們審視了(le)以往版本中的(de)原有元素。我們發現其中的(de) C# 與 Python API,在這(zhè)兩種場(chǎng)景下(xià) API 都屬于原生庫上的(de)打包器,而這(zhè)些庫則采用(yòng) GPL 許可(kě)。我們認爲這(zhè)種方法缺乏可(kě)持續性。因此,我們構建了(le) 100% 純 C# 解決方案以實現這(zhè)些協議(yì),這(zhè)意味著(zhe)我們的(de) API 可(kě)以在支持 .NET Core 的(de)任何環境下(xià)運作,利用(yòng) C# 調試器(通(tōng)過 sourcelink)進行調試,并支持多(duō)種底層 Linux 驅動程序(包括 sysfs、libgpoid 以及其它針對(duì)特定主闆的(de)驅動程序)。所有代碼皆遵循 MIT 許可(kě)。與現有技術相比,我們認爲這(zhè)種新方法将給.NET 開發人(rén)員(yuán)帶來(lái)巨大(dà)的(de)便利。
.NET Core 運行時(shí)前滾策略更新
現在,.NET Core 運行時(shí)(更具體地講,運行時(shí)綁定程序)開始提供主版本的(de)前滾選擇策略。運行時(shí)綁定程序将默認啓用(yòng)面向補丁與次版本的(de)前滾功能。我們決定公開一組更爲廣泛的(de)策略,以幫助開發人(rén)員(yuán)快(kuài)速恢複可(kě)能存在的(de)更新問題,但原有前滾操作并不受影(yǐng)響。
我們發布了(le)一項名爲 RollForward 的(de)新屬性,該屬性能夠接受以下(xià)值:
LatestPatch——前滾至最新補丁版本。其會禁用(yòng) Minor 策略。
Minor ——前滾至最早次版本以解決所需次版本缺失問題。如果該次版本存在,則 LatesPatch 策略即可(kě)起效。這(zhè)也(yě)是系統中采用(yòng)的(de)默認策略。
Major ——前滾至最早主版本與最早次版本,以解決所需主版本缺失問題。如果該主版本存在,則随後使用(yòng) Minor 策略。
LatestMinor——前滾至最新次版本,即使存在所請求的(de)次版本亦不受影(yǐng)響。
LatestMajor ——前滾至最新主版本,即使存在所請求的(de)主版本亦不受影(yǐng)響。
Disable ——不進行前滾。僅綁定至指定版本。我們不建議(yì)大(dà)家在常規用(yòng)途中使用(yòng)這(zhè)一選項,因爲其會禁用(yòng)前滾至最新補丁後版本的(de)功能。僅建議(yì)您在測試環境中使用(yòng)。
Docker 與 cgroup 限制
很多(duō)開發人(rén)員(yuán)都在利用(yòng)容器技術打包并運行自己的(de)應用(yòng)程序。其中的(de)一大(dà)重要問題,在于容器的(de) CPU 或者内存等資源可(kě)能受到限制。我們早在 2017 年就實現了(le)對(duì)内存限制功能的(de)支持,遺憾的(de)是,我們發現該實現的(de)主動性不足以将容器環境以可(kě)靠方式保持在配置限制之下(xià),意味著(zhe)即使設置了(le)内存限制(特别是小于 500 MB 的(de)情況),應用(yòng)程序仍然有可(kě)能出現 OOM 問題。我們已經在 .NET Core 3.0 當中修複了(le)這(zhè)一問題。這(zhè)一改進意義重大(dà),我們強烈建議(yì)使用(yòng) .NET Core Docker 的(de)用(yòng)戶升級至 .NET Core 3.0。
Docker 資源限制功能構建在 cgroup 基礎之上,而 cgroup 又是一項 Linux 内核功能。從運行時(shí)的(de)角度來(lái)看,我們需要以 cgroup 基元爲目标。
大(dà)家可(kě)以利用(yòng) docker run -m 參數來(lái)限制容器的(de)可(kě)用(yòng)内存,如下(xià)所示,此示例用(yòng)于創建一個(gè)基于 Alpine 且内存容量爲 4 MB 的(de)容(而後輸出内存限制):
我們還(hái)添加了(le)新的(de)變更,以更好地支持 CPU 限制(–cpus)。其中包括更新運行時(shí)對(duì)十進制 CPU 值進行四舍五入的(de)方式。如果将—cpus 設置爲(足夠)接近某個(gè)較小的(de)整數(例如 1.499999999)的(de)值,則運行時(shí)會對(duì)該值進行四舍五入(這(zhè)種情況下(xià)将四舍五入爲 1)。結果就是,運行時(shí)所使用(yòng)的(de) CPU 數量低于需求,從而導緻 CPU 資源不足。通(tōng)過對(duì)該值進行直接進位,運行時(shí)在理(lǐ)論上會增加 OS 線程調度程序的(de)壓力,但即使是在最極端的(de)情況下(xià)(–cpus=1.000000001,以往 其會被四舍五入爲 1,但現在會直接進位爲 2),我們也(yě)沒有發現 CPU 出現任何性能下(xià)降。
下(xià)一步是确保線程池遵循 CPU 限制。線程池算(suàn)法中有一部分(fēn)負責計算(suàn) CPU 的(de)繁忙時(shí)間,也(yě)就是計算(suàn)可(kě)用(yòng) CPU 容量。通(tōng)過在計算(suàn) CPU 繁忙時(shí)間當中考慮 CPU 限制,我們得(de)以避免線程池在争用(yòng)中執行的(de)各種試探操作:一種方法可(kě)能嘗試分(fēn)配更多(duō)線程以增加 CPU 繁忙時(shí)間;但另一種方法則可(kě)能嘗試分(fēn)配更少線程,以避免不必要的(de)線程浪費。
默認情況下(xià)降低 GC 堆大(dà)小
在緻力于改善對(duì) docker 内存限制支持能力的(de)同時(shí),我們也(yě)受到了(le)啓發,并著(zhe)手對(duì)通(tōng)用(yòng) GC 策略加以更新,旨在爲更爲廣泛的(de)應用(yòng)程序的(de)内存使用(yòng)率帶來(lái)改善(即使未運行在容器之内)。這(zhè)些變更使得(de)第 0 代預算(suàn)分(fēn)配能夠更好地與現代處理(lǐ)器的(de)緩存大(dà)小及緩存層級保持一緻。
我們的(de)團隊成員(yuán) Damian Edwards 注意到,ASP.NET 基準測試的(de)内存使用(yòng)量減少了(le)一半,但其它性能指标并未出現任何負面影(yǐng)響。這(zhè)是一項驚人(rén)的(de)進步!如他(tā)所言,這(zhè)些将成爲新的(de)默認設置,且不需要對(duì)您的(de)代碼做(zuò)出任何修改(隻需采用(yòng) .NET Core 3.0 即可(kě))。
當然,我們在 ASP.NET 基準測試中觀察到的(de)内存節約效果,可(kě)能代表 / 不代表您的(de)實際體驗。我們希望聽(tīng)到更多(duō)朋友在實際應用(yòng)程序内存使用(yòng)量方面觀察到的(de)結果。
改善對(duì)多(duō)處理(lǐ)器設備的(de)支持能力
基于 .NET 的(de) Windows 傳統,GC 需要配合 Windows 處理(lǐ)器組概念才能支持包含 64 塊以上處理(lǐ)器的(de)計算(suàn)機。這(zhè)一實現早在 5 到 10 年前的(de) .NET Framework 當中即已完成。但利用(yòng) .NET Core,我們最初選擇了(le) Linux PAL 以實現類似的(de)概念——雖然 Linux 當中不存在這(zhè)一原生概念。此後,我們在 GC 當中放棄了(le)這(zhè)一概念,并将其轉化(huà)爲 Windows APL。
GC 現在公開了(le)一個(gè)配置開關,即 GCHeapAffinitizeRanges,用(yòng)于在包含 64 個(gè)以上處理(lǐ)器的(de)計算(suàn)機上指定相似的(de)掩碼。
GCLarge Page 支持
Large Pages 或者叫 Huge Pages 是一項功能,操作系統可(kě)利用(yòng)其構建起大(dà)于原生頁面大(dà)小(通(tōng)常爲 4K)的(de)内存區(qū)域,從而提高(gāo)調用(yòng)這(zhè)些大(dà)頁面的(de)應用(yòng)程序的(de)性能表現。
當發生虛拟到物(wù)理(lǐ)地址的(de)轉換時(shí),系統會首先查詢(通(tōng)常爲并行)被稱爲轉換後備緩沖區(qū)(TLB)的(de)高(gāo)速緩存,以檢查是否存在可(kě)用(yòng)于所訪問虛拟地址的(de)可(kě)用(yòng)物(wù)理(lǐ)翻譯,以避免進行可(kě)能占用(yòng)大(dà)量資源的(de)頁面移動操作。每個(gè)大(dà)頁面翻譯都需要使用(yòng) CPU 内部的(de)一個(gè)翻譯緩沖區(qū)。該緩沖區(qū)的(de)大(dà)小通(tōng)常要比本地頁面大(dà)三個(gè)數量級;這(zhè)能夠極大(dà)提高(gāo)轉換緩沖區(qū)的(de)效率,從而改善内存在頻(pín)繁訪問下(xià)的(de)性能。在具有雙層 TLB 的(de)虛拟機當中,這(zhè)一改進顯得(de)尤爲重要。
GC 現在能夠利用(yòng) GCLargePages 選項功能進行配置,從而選擇在 Windows 上分(fēn)配大(dà)頁面。利用(yòng)大(dà)頁面能夠減少 TLB 遺漏,進而在總體上提高(gāo)應用(yòng)程序的(de)性能;但是,這(zhè)項功能也(yě)有著(zhe)自己的(de)局限,應當認真考量。Bing.com 就采用(yòng)了(le)這(zhè)項功能,并切實獲得(de)了(le)性能提升。
.NET Core 版本 API
我們在.NET Core 3.0 當中對(duì).NET Core 版本 API 做(zuò)出改進,現在它們能夠返回您所需要的(de)版本信息。這(zhè)些變更雖然在客觀上帶來(lái)了(le)便利,但卻存在技術破壞性,而且有可(kě)能影(yǐng)響到依賴現有版本 API 獲取各類信息的(de)應用(yòng)程序。
現在,大(dà)家可(kě)以訪問以下(xià)版本信息:
Event Pipe 改進 Event Pipe 現在支持多(duō)個(gè)會話(huà)。這(zhè)意味著(zhe)大(dà)家可(kě)以使用(yòng) EventListener 在進程内使用(yòng)事件,同時(shí)獲得(de)進程外 event pipe 客戶端。
添加了(le)新的(de) Perf Counters:
GC 中的(de)時(shí)間百分(fēn)比
Gen 0 堆大(dà)小
Gen 1 堆大(dà)小
Gen 2 堆大(dà)小
LOH 堆大(dà)小
分(fēn)配率
加載組件數量
ThreadPool 線程數量
鎖定争用(yòng)率
ThreadPool 工作條目隊列
ThreadPool 已完成工作項比例
現在,大(dà)家可(kě)以使用(yòng)同樣的(de) Event Pipe 基礎設施實現 Profiler 險别。
HTTP/2 支持
現在,我們在 HttpClinet 當中支持 HTTP/2。采用(yòng)新協議(yì)是爲了(le)滿足某些 API 的(de)要求,例如 gRPC 與 Apple Push Notification Service。我們希望未來(lái)會有更多(duō)服務使用(yòng) HTTP/2 協議(yì)。此外,ASP.NET 也(yě)同樣支持 HTTP/2。
備注:首選 HTTP 協議(yì)版本将通(tōng)過 TLS/ALPN 協商,并僅在服務器選擇使用(yòng) HTTP/2 時(shí)才加以使用(yòng)。
分(fēn)層編譯
分(fēn)層編譯是 .NET Core 2.1 中的(de)一項可(kě)選功能,該功能使得(de)運行時(shí)能夠更靈活地使用(yòng)即時(shí)(JIT)編譯器,從而在啓動時(shí)獲得(de)更佳性能并最大(dà)程度提升吞吐量。.NET Core 3.0 在默認情況下(xià)即啓用(yòng)這(zhè)一功能。去年,我們對(duì)該功能做(zuò)出了(le)一系列改進,包括針對(duì)各類工作負載(例如網站、PowerShell 以及 Windows 桌面應用(yòng)程序)進行測試。性能确實迎來(lái)顯著提升,因此我們決定将其作爲默認選項。
IEEE 浮點改進
我們對(duì)浮點 API 進行了(le)更新,以符合 IEEE 754-2008 修訂版的(de)要求。.NET Core 浮點項目的(de)目标,在于公開所有“必要”運算(suàn),以确保其在行爲層面符合 IEEE 提出的(de)規範。
解析與格式化(huà)修複:
正确解析并舍入任何長(cháng)度的(de)輸入。
正确解析并格式化(huà)負零。
通(tōng)過進行不區(qū)分(fēn)大(dà)小寫的(de)檢查,并在适用(yòng)時(shí)允許使用(yòng)可(kě)選前置 + 以正确解析無限與 NaN。
新的(de) Math API:
BitIncrement/BitDecrement ——對(duì)應于 nextUp 與 nextDown IEEE 運算(suàn)。二者分(fēn)别返回大(dà)于或者小于輸入内容的(de)最小浮點數。例如,Math.BitIncrement(0.0)将返回 double.Epsilon。
MaxMagnitude/MinMagnitude——對(duì)應于 maxNumMag 與 minNumMag IEEE 運算(suàn),二者分(fēn)别返回大(dà)于或者小于輸入内容的(de)值。例如,Math.MaxMagnitude(2.0 -3.0) 将返回 -3.0。
ILogB ——對(duì)應于 logB IEEE 運算(suàn),該運算(suàn)将返回一個(gè)整數值,且該值爲輸入參數的(de)以 2 爲底的(de)整數對(duì)數。實際上與 floor(log2(x)) 相同,但舍入誤差最小。
ScaleB——對(duì)應于采用(yòng)整數值的(de) scaleB IEEE 運算(suàn),其相當于返回 x * pow(2,n) 的(de)值,但舍入誤差最小。
Log2——對(duì)應于 log2 IEEE 運算(suàn),返回以 2 爲底的(de)對(duì)數,且舍入誤差最小。
FusedMultiplyAdd ——對(duì)應于 fma IEEE 運算(suàn),負責執行積和(hé)熔加運算(suàn)。具體而言,其通(tōng)過一次運算(suàn)完成(xy)+ z 運算(suàn),同時(shí)使舍入誤差最小。以 FusedMultiplyAdd (1e308, 2.0, -1e308) 爲例,其返回值爲 1e308。常規(1e308
2.0)-1e308 将返回 double.PositiveInfinity。
CopySign ——對(duì)應于 copySign IEEE 運算(suàn),其返回 x 的(de)值,但同時(shí)帶有 y 符号。
.NET 平台相關改進
我們添加了(le)一些新的(de) API,用(yòng)以訪問某些面向性能的(de) CPU 指令,包括 SIMD 或 Bit Manipulation 指令集。這(zhè)些指令能夠在某些場(chǎng)景下(xià)實現巨大(dà)的(de)性能提升,例如更高(gāo)效地并行處理(lǐ)數據。除了(le)公開這(zhè)些可(kě)供應用(yòng)程序使用(yòng)的(de) API 之外,我們還(hái)開始利用(yòng)相關指令對(duì).NET 庫進行提速。
以下(xià) CoreCLR PRs 通(tōng)過實現或者使用(yòng)的(de)方式展示了(le)一部分(fēn)内部函數:
實現簡單 SSE2 硬件内部函數
實現 SSE 硬件内部函數
Arm64 Base 硬件内部函數
面向 LocateFound使用(yòng) TZCNT 與 LZCNT
現可(kě)在 Linux 上支持 TLS 1.3 與 OpenSSL 1.1.1
.NET Core 現在能夠利用(yòng) OpenSSL 1.1.1 中的(de) TLS 1.3 支持能力。TLS 1.3 能夠爲 OpenSSL 團隊提供多(duō)項優勢:
通(tōng)過減少客戶端與服務器間的(de)往返次數縮短連接時(shí)長(cháng)。
通(tōng)過消除各種過時(shí)及不安全的(de)加密算(suàn)法、同時(shí)加密更多(duō)連接握手,以提高(gāo)安全性。
.NET Core 3. 能夠利用(yòng) OpenSSL 1.1.1、OpenSSL 1.1.0 以及 OpenSSL 1.0.2(以及您能夠在 Linux 系統上找到任何最佳版本)。如果客戶端與服務器均支持 TLS 1.3,且 OpenSSL 1.1.1 可(kě)用(yòng),則 SslStream 與 HttpClinet 類型将在使用(yòng) SslProtocols.None 時(shí)選擇 TLS 1.3(系統默認協議(yì))。
.NET Core 後續還(hái)将在 Windows 與 MacOS 上支持 TLS 1.3——預計以自動化(huà)方式實現,敬請期待。
加密
我們增加了(le)對(duì) AES-GCM 以及 AES-CCM 加密機制的(de)支持,這(zhè)些加密算(suàn)法将通(tōng)過 System.Security.Cryptography.AesGcm 與 System.Security.Cryptography.AesCcm 實現。這(zhè)些算(suàn)法皆屬于帶關聯數據的(de)加密認證(AEAD)算(suàn)法,同時(shí)也(yě)是首批被添加至 .NET Core 當中的(de)驗證加密(AE)算(suàn)法。
.NET Core 3.0 現在支持通(tōng)過标準格式導入及導出非對(duì)稱公鑰與私鑰,且無需使用(yòng) X.509 證書(shū)。
所有密鑰類型(RSA、DSA、ECDsa、ECDiffieHellman)都支持 X.509 SubjectPublicKeyInfo 格式的(de)公鑰,以及 PKCS#8 PrivateKeyInfo 與 PKCS#8 EncryptedPrivateKeyInfo 格式的(de)私鑰。此外,RSA 還(hái)支持 PKCS#1 RSAPublicKey 與 PKCS#1 RSAPrivateKey。所有導出方法皆産生 DER 編碼的(de)二進制數據,而導入方法也(yě)基本相同;如果某一密鑰以文本友好的(de) PEM 格式存儲,則調用(yòng)程序将需要先對(duì)内容進行 base64 解碼,而後才能進行方法導入。
PKCS#8 文件可(kě)通(tōng)過 System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo 類進行檢查。
PFX/PKCS#12 文件可(kě)分(fēn)别通(tōng)過 System.Security.Cryptography.Pkcs.Pkcs12Info 與 System.Security.Cryptography.Pkcs.Pkcs12Builder 進行檢查與修改。
支持新的(de)日本年号(令和(hé))
2019 年 5 月(yuè) 1 日,日本開始使用(yòng)新的(de)年号——令和(hé)。因此,支持日語日曆的(de)軟件(例如 .NET Core)必須進行更新以支持這(zhè)一新年号。.NET Core 與 .NET Framework 已經更新,現在可(kě)以正确處理(lǐ)新年号下(xià)的(de)日文日期格式與解析結果。
.NET 依賴于操作系統或其他(tā)更新以正确處理(lǐ)令和(hé)日期。如果您或者您的(de)客戶使用(yòng) Windows 系統,請下(xià)載 Windows 版本的(de)最新更新。如果您運行的(de)是 MacOS 或者 Linux,請下(xià)載并安裝支持日本新年号的(de) ICU 64.2 版本。
Assembly Load Context 改進
關于 AssemblyLoadContext 的(de)改進:
實現上下(xià)文命名
添加 ALC 枚舉功能
對(duì) ALC 内程序集進行枚舉的(de)功能
實現類型具體化(huà)——旨在簡化(huà)實例化(huà)(簡單場(chǎng)景不需要自定義類型)
通(tōng)過将 AssemblyDependencyResolyer 與自定義 AssemblyLoadContext 加以結合,應用(yòng)程序将能夠在加載插件的(de)過程中,從各個(gè)正确位置加載該插件所需要的(de)依賴項,且某一插件的(de)依賴項不會與其他(tā)插件的(de)依賴項發生沖突。
Assembly 可(kě)卸載性
Assembly 的(de)可(kě)制裁性是 AssemblyLoadContext 中提供的(de)一項新功能。從 API 的(de)角度來(lái)看,這(zhè)項新功能具有極高(gāo)的(de)透明(míng)度,且面向部分(fēn)新 API 公開。其允許開發人(rén)員(yuán)對(duì)加載程序的(de)上下(xià)文進行卸載,從而釋放原本被實例化(huà)類型、靜态字段以及程序集本身所占用(yòng)的(de)内存。應用(yòng)程序可(kě)以通(tōng)過這(zhè)種機制實現程序集的(de)永久加載與卸載,且不會引發内存洩漏。
我們希望這(zhè)項新功能被用(yòng)于以下(xià)場(chǎng)景:
需要動态插件加載與卸載的(de)插件使用(yòng)場(chǎng)景。
對(duì)代碼的(de)動态編譯、運行以及刷新。适用(yòng)于網站、腳本引擎等。
加載程序集以進行自我檢查(例如 ReflectionOnlyLoad),但在大(dà)多(duō)數情況下(xià) MetadataLoadContext 仍然是更好的(de)選擇。
利用(yòng) MetadataLoadContext 讀取 Assembly 元數據
我們添加了(le) MetadataLoadContext,希望在不影(yǐng)響調用(yòng)程序域的(de)前提下(xià)讀取 assembly 元數據。各 assembly 這(zhè)以數據的(de)形式讀取,其中包括與當前運行時(shí)環境不同的(de)各類架構及平台上的(de) assembly。MetadataLoadContext 與 ReflectionOnlyLoad 存在一定交集,但後者僅适用(yòng)于 .NET Framework。
MetdataLoadContext 目前通(tōng)過 System.Reflection.MetadataLoadContext 軟件包發布,其屬于 .NET Standard 2.0 軟件包。
MetadataLoadContext 的(de)适用(yòng)場(chǎng)景包括設計時(shí)功能、構建時(shí)工具與運行時(shí)點亮功能等需要将一組 assembly 作爲數據進行檢查,并在執行檢查後釋放所有文件鎖與内存的(de)場(chǎng)景。
Native Hosting 示例
.NET Core 團隊還(hái)發布了(le)一個(gè) Native Hosting 示例,其中展示了(le)在本機應用(yòng)程序當中托管 .NET Core 的(de)相關最佳實踐。
作爲 .NET Core 3.0 中的(de)組成部分(fēn),我們現在面向 .NET Core 本地主機公開了(le)這(zhè)一原本隻通(tōng)過官方 .NET Core 主機爲 .NET Core 托管應用(yòng)程序提供的(de)功能。此項功能主要與 assembly 加載相關,利用(yòng)這(zhè)項功能可(kě)幫助大(dà)家更輕松地構建能夠利用(yòng) .NET Core 完整功能集的(de)本地主機。
其他(tā) API 改進
我們曾在 .NET Core 2.1 版本當中對(duì) Span、Memory 以及其他(tā)相關類型做(zuò)出優化(huà)。現在,span construction、切片、解析以及格式化(huà)等常規操作的(de)執行效果将有所提升。此外,String 等類型也(yě)得(de)到了(le)明(míng)顯改進,能夠在與 Dictionary 及其他(tā)集合共同充當鍵時(shí)擁有更好的(de)執行效率。所有改進開箱即用(yòng),無需對(duì)您的(de)代碼做(zuò)出任何變更。
下(xià)面來(lái)看其它最新改進:
Brotli 内置 HttpClient 支持能力
ThreadPool.UnsafeQueueWorkItem(IThreadPoolWorkItem)
Unsafe.Unbox
CancellationToken.Unregister
複雜(zá)算(suàn)術運算(suàn)符
Socket APIs for TCP 仍然有效
StringBuilder.GetChunks
IPEndPoint 解析
RandomNumberGenerator.GetInt32
System.Buffers.SequenceReader
默認情況下(xià),應用(yòng)程序現在具有原生可(kě)執行文件
.NET Core 應用(yòng)程序現在擁有自己的(de)原生可(kě)執行文件。對(duì)于依賴框架的(de)應用(yòng)程序而言,這(zhè)是一項前所未有的(de)新功能。在此之前,隻有獨立應用(yòng)程序具有可(kě)執行文件。這(zhè)些新的(de)可(kě)執行文件,将在效果上與此前的(de)原生可(kě)執行文件保持一緻:
您可(kě)以雙擊可(kě)執行文件以啓動對(duì)應應用(yòng)程序。
您可(kě)以在 Windows 上使用(yòng) myapp.exe,或者在 Linux 及 MacOS 上使用(yòng)./myapp 通(tōng)過命令提示符啓動應用(yòng)程序。
作爲 build 的(de)組成部分(fēn),新生成的(de)可(kě)執行文件将與您的(de)操作系統以及 CPU 相匹配。例如,如果您使用(yòng)的(de)是 Linux x64 計算(suàn)機,那麽可(kě)執行文件将僅可(kě)在該類型的(de)計算(suàn)機上運行——無法在 Windows 以及 Linux ARM 計算(suàn)機上運行。這(zhè)是因爲可(kě)執行文件使用(yòng)本機代碼(例如 C++)。如果要定位爲其他(tā)機器類型,則需要在發布時(shí)使用(yòng)對(duì)應的(de)運行時(shí)參數。如果願意,您也(yě)可(kě)以繼續使用(yòng) dotnet 命令啓動應用(yòng)程序,而不使用(yòng)原生可(kě)執行文件。
利用(yòng) ReadyToRun 鏡像優化(huà) .NET Core 應用(yòng)
通(tōng)過将應用(yòng)程序 assemblies 編譯爲 ReadyToRun(R2R)格式,可(kě)以改進 .NET Core 應用(yòng)程序的(de)啓動速度。R2R 是一種提前(AOT)編譯格式,在 .NET Core 3.0 版本中以可(kě)選功能的(de)形式提供。
R2R 二進制文件能夠減少應用(yòng)程序加載時(shí) JIT 需要完成的(de)工作量,從而提高(gāo)啓動性能。二進制文件當中包含與 JIT 産生的(de)代碼相似的(de)本機代碼,能夠通(tōng)過分(fēn)擔 JIT 的(de)負載壓力帶來(lái)更理(lǐ)想的(de)啓動性能。R2R 二進制文件體積較大(dà),因爲其中既包含中間語言(IL)代碼(某些情況下(xià)仍然需要此代碼),同時(shí)包含同一代碼的(de)本機版本,用(yòng)以改善啓動速度。
要啓用(yòng) R2R 編譯:
将 PublishReadyToRun 屬性設置爲 true。
使用(yòng) RuntimeIdentifie 顯式參數發布。
備注:在編譯應用(yòng)程序 assemblies 時(shí),生成的(de)本機代碼将特定于當前平台與架構(因此,大(dà)家在發布時(shí)必須指定有效的(de) RuntimeIdentifier)。
以下(xià)爲具體示例:
使用(yòng)以下(xià)命令進行發布:
備注:RuntimeIdentifier 可(kě)設置爲其他(tā)操作系統或者芯片類型,亦可(kě)在項目文件内進行設置。
Assembly Linking
.NET core 3.0 SDK 附帶一款工具,可(kě)通(tōng)過分(fēn)析 IL 與修剪未使用(yòng)的(de) assemblies 以降低應用(yòng)程序的(de)體積。這(zhè)是 .NET Core 3.0 中的(de)另一項發行時(shí)可(kě)選功能。
在 .NET Core 當中,我們可(kě)以随時(shí)發布包含代碼運行所需的(de)一切元素的(de)自包含應用(yòng)程序,而無需在部署目标上安裝 .NET。在某些情況下(xià),該應用(yòng)僅需要框架中的(de)一小部分(fēn)即可(kě)運行,因此修剪掉不必要的(de)框架部分(fēn)能夠有效降低應用(yòng)程序體積。我們利用(yòng) IL linker 對(duì)應用(yòng)程序的(de) IL 進行掃描,從而檢測出哪些代碼确有必要,而後對(duì)未使用(yòng)的(de)框架庫進行修剪。這(zhè)能夠顯著降低某些應用(yòng)程序的(de)體積。一般來(lái)講,小型工具控制台類應用(yòng)程序的(de)瘦身效果最爲明(míng)顯,因爲其通(tōng)常使用(yòng)框架中的(de)較小子集,且調整難度更低。
要使用(yòng) linker 工具:
将 PublishTrimmed 的(de)屬性設置爲 true。
将 RuntimeIdentifier 作爲顯式參數進行發布。
以下(xià)爲相關示例:
使用(yòng)以下(xià)命令進行發布:
備注:RuntimeIdentifier 可(kě)設置爲其他(tā)操作系統或者芯片類型,亦可(kě)在項目文件内進行設置。
根據應用(yòng)程序代碼的(de)實際調用(yòng)情況,所發布的(de)輸出結果将包含框架庫中的(de)一個(gè)子集。對(duì)于最簡單的(de) helloworld 應用(yòng),linker 工具能夠将應用(yòng)程序體積縮小 68 MB 到 28 MB。
在修剪之後,需要使用(yòng)反射或者相關動态功能的(de)應用(yòng)程序或者框架(包括 ASP .NET Core 以及 WPF)通(tōng)常無法正常執行,這(zhè)是因爲 linker 無法識别這(zhè)種動态行爲,因此一般不能确定反射操作在運行時(shí)中需要的(de)框架類型。要修剪這(zhè)類應用(yòng)程序,大(dà)家需要告知 linker 相關代碼當中所依賴的(de)各類工具包或框架以及各種相關信息類型。請确保您在修剪之後對(duì)應用(yòng)程序進行全面測試,我們也(yě)正在 .NET 5 當中對(duì)這(zhè)一體驗做(zuò)出改進。
關于 IL Linker 的(de)更多(duō)細節信息,請參閱說明(míng)文檔或者訪問 mono/linker 庫。
備注:在 .NET Core 之前的(de)版本當中,ILLink Tasks 以外部 NuGet 軟件包的(de)形式提供,其中包含多(duō)種相同功能。但相關軟件包現已不再受到支持,請更新至 .NET Core 3.0 SDK 以獲取我們爲您準備的(de)全新體驗.
Linker 與 R2R 編譯器可(kě)同時(shí)作用(yòng)于一款應用(yòng)程序。一般來(lái)講,Linker 能夠使您的(de)應用(yòng)程序體積更小,而 R2R 則能夠再次恢複其體積,并在性能上帶來(lái)顯著提升。大(dà)家可(kě)以在各種配置當中進行測試,以了(le)解各個(gè)選項帶來(lái)的(de)具體影(yǐng)響。
發布單文件可(kě)執行文件
現在,大(dà)家可(kě)以利用(yòng) dotnet publish 命令發布單文件可(kě)執行文件了(le)。這(zhè)種形式的(de)單一 EXE 實際上是一個(gè)自解壓可(kě)執行文件,其中以資源形式包含所有依賴項(包括本地依賴項)。在啓動時(shí),它會将所有依賴項複制到某個(gè)臨時(shí)目錄,通(tōng)過該目錄進行加載。依賴項隻需要解壓一次,後續啓動将速度極快(kuài),不再存在任何性能損失。
大(dà)家可(kě)以通(tōng)過在項目文件中添加 PublishSingleFile 屬性,或者在命令行中添加新開關的(de)方式啓用(yòng)這(zhè)一發布選項。
要生成獨立的(de)單 EXE 應用(yòng)程序,以下(xià)示例爲 64 位 Windows 系統下(xià)的(de)命令:
備注:RuntimeIdentifier 可(kě)設置爲其他(tā)操作系統或者芯片類型,亦可(kě)在項目文件内進行設置。
若需了(le)解更多(duō)細節信息,請參閱單文件捆綁器說明(míng)文檔。
Assembly 修剪器、提前編譯(通(tōng)過 crossgen)以及單文件捆綁功能皆爲 .NET Core 3.0 中提供的(de)全新選項,大(dà)家可(kě)以根據需求獨立使用(yòng)或者以組合方式使用(yòng)。相信一部分(fēn)用(yòng)戶可(kě)能喜愛(ài)通(tōng)過提前編譯器提供的(de)單 exe 發布選項,而非我們在.NET Core 3.0 當中提供的(de)自解壓可(kě)執行文件方法。.NET 5 發行版當中将正式提供提前編譯器方法。
dotnet build 現在可(kě)複制依賴項
dotnet build 現在能夠在 build 操作過程當中,将應用(yòng)程序中的(de) NuGet 依賴項從 NuGet 緩存複制到 build 輸出文件夾内。在此版本之前,各依賴項僅能作爲 dotnet publish 中的(de)一部分(fēn)進行複制。此次變更使您能夠利用(yòng) xcopy 将 build 輸出至不同計算(suàn)機當中。
除此之外,您還(hái)需要單獨發布 linking 以及 razor page publishing 等操作。
2
.NET Core 工具:本地安裝
.NET Core 工具也(yě)經過更新以支持本地安裝。這(zhè)些工具比 .NET Core 2.1 版本中的(de)原有全局工具更強大(dà)。
本地安裝具有以下(xià)特性:
限制工具的(de)使用(yòng)範圍。
始終使用(yòng)該工具的(de)某一特定版本,該版本可(kě)能不同于全局安裝工具或者其它本地安裝工具。具體基于本地工具 manifest 文件中定義的(de)版本。
可(kě)使用(yòng) dotnet 命令啓動,例如 dotnet mytool。
備注:請參閱本地工具早期預覽版說明(míng)文檔以了(le)解更多(duō)細節信息。
.NET Core SDK 安裝程序現在将就地升級
Windows 版本的(de) .NET Core SDK MSI 安裝程序将迎來(lái)就地升級。這(zhè)将減少開發者計算(suàn)機及生産計算(suàn)機上所需安裝的(de) SDK 數量。
此項升級策略将專門針對(duì) .NET Core SDK 功能範圍。各功能範圍在版本号中以最後三位數字中的(de)百位體現,例如 3.0.101 與 3.0.201 代表兩個(gè)不同的(de)版本功能範圍,而 3.0.101 與 3.0.199 則處于同一版本功能範圍。
這(zhè)意味著(zhe)當 .NET Core SDK 3.0.101 正式發布并安裝完畢後,.NET Core SDK 3.0.100 将被從計算(suàn)機中删除(如果存在)。當 .NET Core SDK 3.0.200 可(kě)用(yòng)并安裝在同一台計算(suàn)機上時(shí),.NET Core SDK 3.0.101 則不會被删除。在這(zhè)種情況下(xià),系統仍将默認使用(yòng) .NET Core SDK 3.0.200,但如果将其配置爲通(tōng)過 global.json 起效,則系統仍然使用(yòng) .NET Core SDK 3.0.101(或者更高(gāo)版本的(de).1xx 版本)。
這(zhè)種方法與 global.json 的(de)行爲保持一緻,允許在各補丁版本之間進行前滾 ,但無法跨越 SDK 功能範圍。因此,通(tōng)過 SDK 安裝程序并進行升級,可(kě)确保應用(yòng)程序不會因缺少 SDK 而發生錯誤。對(duì)于已經安裝了(le) Visual Studio 必要 SDK 的(de)用(yòng)戶,其功能範圍也(yě)将與 Visual Studio 安裝情況保持一緻。
若需了(le)解更多(duō)細節信息,請參閱:
.NET Core 版本控制
删除.NET Core SDK 版本
.NET Core SDK 體積改進
在 .NET Core 3.0 當中,.NET Core SDK 的(de)體積明(míng)顯更小。主要原因在于,我們轉而采用(yòng)出于各種目的(de)(引用(yòng) assembiles、框架、模闆等)的(de)專用(yòng)“内置包”,從而改變了(le)我們構建 SDK 的(de)方式。在以往的(de)版本(包括 .NET Core 2.2)當中,我們一直利用(yòng) NuGet 軟件包構建 SDK,但其中包含大(dà)量并不需要的(de)構件,且對(duì)存儲空間造成嚴重浪費。
.NET Core 3.0 SDK 體積(括号中爲體積變量)
Linux 與 MacOS 版本的(de)體積變化(huà)最爲顯著,相比之下(xià) Windows 版本的(de)改進較小,這(zhè)是因爲我們在 .NET Core 3.0 當中添加了(le) WPF 與 Windows Forms。令人(rén)驚訝的(de)是,盡管新增了(le) WPF 與 Windows Forms,安裝程序的(de)體積仍然比原先小了(le)一點。
大(dà)家也(yě)可(kě)以在 .NET Core SDK Docker 鏡像當中感受到這(zhè)一瘦身效果(僅限于 x64 Debian 與 Alpine)。
大(dà)家可(kě)以在 .NET Core 3.0 SDK 體積改進文檔中了(le)解我們如何計算(suàn)這(zhè)些文件的(de)大(dà)小。這(zhè)裏提供詳細的(de)說明(míng),您可(kě)以遵循同樣的(de)方法在自己的(de)環境中運行測試。
Docker 發布更新
微軟各團隊目前都在面向微軟容器注冊表(MCR)發布新的(de)容器鏡像。這(zhè)一變化(huà)主要有兩大(dà)原因:
将微軟提供的(de)容器鏡像協同至多(duō)個(gè)注冊表,包括 Docker Hub 與 Red Hat。
利用(yòng)微軟 Azure 作爲全球 CDN 以交付微軟提供的(de)容器鏡像。
在.NET 團隊,我們目前将所有 .NET Core 鏡像發布至 MCR。我們在 Docker Hub 上維護有自己的(de)主頁,并打算(suàn)長(cháng)期保持運營。在另一方面,MCR 并不提供類似的(de)頁面,但可(kě)以通(tōng)過 Docker Hub 等公共注冊表爲用(yòng)戶提供與鏡像有關的(de)信息。Microsoft.dotnet 以及 microsoft.dotnet-nightly 等舊(jiù)有代碼庫鏈接現在都已經指向新的(de)地址。不過舊(jiù)有位置中的(de)各鏡像仍将存在,不會被删除。
在支持生命周期之内,我們将繼續爲 .NET Core 各個(gè)版本的(de)代碼庫提供浮動标記服務。例如,2.1-sdk、2.2-runtime 以及 lastest 就屬于此類浮動标記。像 2.1.2-sdk 這(zhè)類包含三個(gè)數字的(de)标簽将不再提供,我們已經在版本号内加以體現。接下(xià)來(lái),我們将僅通(tōng)過 MCR 支持 .NET Core 3.0 鏡像。
例如,現在用(yòng)于提取 3.0 SDK 鏡像的(de)正确标簽字符串應該爲:
新的(de) MCR 字符串将由 docker pull 以及 Dockerfile FROM 語句共同使用(yòng)。
感興趣的(de)朋友可(kě)以參閱微軟容器注冊表中的(de)現有 .NET Core 鏡像以了(le)解更多(duō)細節信息。
SDK Docker 鏡像中包含 PowerShell Core
應社區(qū)的(de)要求,PowerShell Core 已經被添加至 .NET Core SDK Docker 容器鏡像當中。PowerShell Core 是一套跨平台(Windows、Linux 以及 MacOS)自動化(huà)與配置工具 / 框架,能夠與大(dà)家的(de)現有工具良好協作,并針對(duì)結構化(huà)數據(例如 JSON)CSV、XML 等)、REST API 以及對(duì)象模型進行了(le)優化(huà)。其中包含一個(gè)命令行 shell、一種相關腳本語言以及一套用(yòng)于處理(lǐ) cmdlets 的(de)框架。
現在,大(dà)家可(kě)以通(tōng)過以下(xià) Docker 命令将 PowerShell Core 視爲 .NET Core SDK 容器鏡像中的(de)一部分(fēn):
目前隻有兩種将 PowerShell 引入 .NET Core SDK 容器鏡像的(de)方法,具體如下(xià):
面向任意操作系統利用(yòng) PowerShell 語法編寫 .NET Core 應用(yòng)程序 Dockerfiles。
編寫能夠輕松實現容器化(huà)的(de) .NET Core 應用(yòng)程序 / 庫構建邏輯。
以下(xià)爲容器化(huà) build(存儲卷挂載)的(de) PowerShell 啓動語法示例:
爲了(le)讓第二條示例命令正常起效,我們需要在 Linux 上确保.ps1 文件具有以下(xià)格式,并需要利用(yòng) Unix(LF)而非 Windows(CRLF)作爲行尾以執行格式化(huà):
備注:PowerShell Core 目前已經作爲.NET Core 3.0 SDK 容器鏡像的(de)一部分(fēn)進行發布,而不再歸屬于 .NET Core 3.0 SDK。
紅帽軟件支持
2015 年 4 月(yuè),我們宣布 .NET Core 将全面登陸 Red Hat Enterprise Linux。通(tōng)過與紅帽方面的(de)出色工程合作,.NET Core 1.0 于 2016 年 6 月(yuè)以組件的(de)形式出現在紅帽系列軟件當中。另外,在與紅帽工程師們的(de)持續交流當中,我們也(yě)了(le)解到 Linux 社區(qū)在軟件發布方面的(de)反饋與意見。
過去四年以來(lái),紅帽公司先後發布了(le)多(duō)次面向 .NET Core 的(de)更新與大(dà)版本升級,包括 2.1 與 2.2 版本。在 .NET Core 2.2 版本當中,紅帽公司将其 .NET Core 産品擴展至包括 OpenShift 在内的(de)多(duō)個(gè)平台。而随著(zhe) RHEL 8 的(de)發布,我們也(yě)高(gāo)興地看到微軟 .NET Core 2.1 以及即将推出的(de) 3.0 版本都被納入紅帽 Application Streams 當中。
3
總結
.NET Core 3.0 是 .NET Core 發展曆程中的(de)又一重要新版本,其中帶來(lái)了(le)大(dà)量改進。我們建議(yì)大(dà)家盡快(kuài)著(zhe)手采用(yòng)新的(de) .NET Core 3.0。新版本通(tōng)過多(duō)種方式對(duì) .NET Core 做(zuò)出巨大(dà)改進,例如顯著降低了(le) SDK 的(de)體積、極大(dà)提升對(duì)于關鍵場(chǎng)景(例如容器以及 Windows 桌面應用(yòng)程序)的(de)支持效果。受到篇幅所限,這(zhè)裏無法一一列出其它小的(de)改進,但相信随著(zhe)時(shí)間的(de)推移,大(dà)家一定能夠從這(zhè)些細節增強中受益。
最後,希望大(dà)家能夠在接下(xià)來(lái)的(de)使用(yòng)當中與我們分(fēn)享體驗與感受。希望開發者喜歡 .NET Core 3.0,我們也(yě)熱(rè)切希望根據大(dà)家的(de)喜好對(duì)産品進行打磨。
https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0/
責任編輯:中山網站建設
【網訊網絡】國家高(gāo)新技術企業》十年專注軟件開發,網站建設,網頁設計,APP開發,小程序,微信公衆号開發,定制各類企業管理(lǐ)軟件(OA、CRM、ERP、訂單管理(lǐ)系統、進銷存管理(lǐ)軟件等)!服務熱(rè)線:0760-88610046、13924923903,http://www.wansion.net
*請認真填寫需求,我們會在24小時(shí)内與您取得(de)聯系。