.NET Conf 2019 大會上宣佈.NET Core 3.0的發佈。它包括許多改進,包括添加Windows窗體和WPF,添加新的JSON API,對ARM64的支持以及全面提高的性能。C# 8也是此發行版的一部分,其中包括可為空,非同步流和更多模式。包含F#4.7,專註於放寬語法並定位.NET ... ...
宣佈.NET Core 3.0 發佈
很高興宣佈.NET Core 3.0的發佈。它包括許多改進,包括添加Windows窗體和WPF,添加新的JSON API,對ARM64的支持以及全面提高的性能。
C# 8 也是此發行版的一部分,其中包括可為空,非同步流和更多模式。包含F#4.7,專註於放寬語法並定位.NET Standard 2.0。可以立即開始將現有項目更新為目標.NET Core 3.0。該版本與以前的版本相容,從而使更新變得容易。
觀看團隊和社區在.NET Conf上談論.NET的事情,現在直播
可以下載適用於Windows,macOS和Linux的.NET Core 3.0:
-
Snap安裝程式
-
Docker映像
ASP.NET Core 3.0和EF Core 3.0也發佈
Visual Studio 2019 16.3和適用於Mac 8.3的Visual Studio也在今天發佈,並且需要更新才能將.NET Core 3.0與Visual Studio一起使用。
.NET Core 3.0是Visual Studio 2019 16.3的一部分。只需升級Visual Studio 2019 16.3就可以獲取.NET Core。
感謝所有為.NET Core 3.0做出貢獻的人!數百人參與了此版本的發佈,包括社區的重大貢獻。
發行說明:
-
.NET Core 3.0發行說明
-
.NET Core 2.2-> 3.0 API差異
-
.NET Core 3.0貢獻者列表
-
GitHub發佈
-
.NET Core 3.0 問題的GitHub問題
關於.NET Core 3.0
在深入探究.NET Core 3.0中的所有新功能之前,需要引起一些關鍵的改進和指導,以引起註意。這是快速打孔清單。
-
.NET Core 3.0已經在dot.net和Bing.com上托管了幾個月,已經通過了測試。許多其他Microsoft團隊很快將在生產中的.NET Core 3.0上部署大型工作負載。
-
在許多組件中,性能都得到了極大的提高,並且在.NET Core 3.0中的性能改進中進行了詳細介紹。
-
C#8添加非同步流,範圍/索引,更多模式和可為空的引用類型。Nullable使可以直接針對導致的代碼缺陷NullReferenceException。框架庫的最底層已被註釋,以便知道何時可以期待null。
-
F#4.7致力於通過隱式yield表達式和一些語法放鬆使某些事情變得容易。它還包含對的支持LangVersion,並nameof在預覽中附帶並打開了靜態類。F#核心庫現在還針對.NET Standard 2.0。可以在發佈F#4.7中閱讀更多內容。
-
.NET Standard 2.1增加了可以在可與.NET Core和Xamarin一起使用的代碼中使用的類型集。.NET Standard 2.1包括.NET Core 2.1以後的類型。
-
.NET Core現在支持Windows窗體和WPF(和開源)的Windows桌面應用程式。WPF設計器是Visual Studio 2019 16.3的一部分。Windows窗體設計器仍處於預覽狀態,可以通過VSIX下載獲得。
-
現在,.NET Core應用程式預設情況下具有可執行文件。在過去的發行版中,需要通過dotnet命令來啟動應用,例如dotnet myapp.dll。現在可以使用特定於應用程式的可執行文件(例如myapp或)啟動應用程式./myapp,具體取決於操作系統。
-
添加了高性能JSON API,用於讀取器/寫入器,對象模型和序列化方案。這些API從頭開始構建,Span<T>併在幕後使用UTF8而不是UTF16(例如string)。這些API最小化分配,從而提高了性能,減少了垃圾收集器的工作。請參閱.NET Core 3.0中JSON的未來。
-
預設情況下,垃圾收集器使用較少的記憶體,通常少得多。對於許多應用程式托管在同一伺服器上的情況,此改進非常有用。垃圾收集器也進行了更新,以更好地利用64核以上的機器上的大量核。
-
.NET Core已針對Docker進行了強化,以使.NET應用程式在容器中可預測且有效地工作。已將容器配置為有限的記憶體或CPU時,垃圾收集器和線程池已更新為更好地工作。.NET Core泊塢窗映像較小,尤其是SDK映像。
-
現在支持Raspberry Pi和ARM晶元以支持IoT開發,包括使用遠程Visual Studio調試器。可以使用新的GPIO API部署可監聽感測器的應用程式,併在顯示器上列印消息或圖像。ASP.NET可用於將數據公開為API或允許配置IoT設備的站點。
-
.NET 3.0的核心是“當前”版本,將被所取代.NET 3.1的核心,目標是2019年十一月.NET 3.1的核心將是一個長期支持(LTS)版本(支持至少3年)。我們建議採用.NET Core 3.0,然後採用3.1。升級非常容易。
-
.NET Core 2.2將於12/23停止服務,因為它是以前的“當前”版本。請參閱.NET Core支持策略。
-
經過與Red Hat的多年合作,.NET Core 3.0將隨RHEL 8在Red Hat Application Streams中一起提供。
-
對於要使用.NET Core 3.0的Windows上的Visual Studio用戶,Visual Studio 2019 16.3是必需的更新。
-
對於要使用.NET Core 3.0的Mac用戶,Visual Studio for Mac 8.3是必需的更新。
-
Visual Studio Code用戶應始終始終使用最新版本的C#擴展名,以確保最新的方案能夠正常工作,包括針對.NET Core 3.0。
-
.NET Core 3.0的Azure App Service部署當前正在進行中。
-
.NET Core 3.0的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窗體和WPF應用程式僅在Windows上運行。
Chip support follows:
-
Windows,macOS和Linux上的x64
-
Windows上的x86
-
Windows和Linux上的ARM32
-
Linux上的ARM64(內核4.14+)
註意:請確保.NET Core 3.0 ARM64部署使用Linux內核4.14版本或更高版本。例如,Ubuntu 18.04滿足此要求,但16.04不滿足。
WPF和Windows窗體
可以在Windows上使用.NET Core 3構建WPF和Windows Forms應用程式。從項目一開始,我們就已經制定了強大的相容性目標,以使將桌面應用程式從.NET Framework遷移到.NET Core變得容易。我們已經聽到許多開發人員的反饋,這些開發人員已經成功地將其應用程式移植到.NET Core 3.0,該過程非常簡單。在很大程度上,我們按原樣使用WPF和Windows窗體,並使它們在.NET Core上運行。
工程項目與之大不相同,但這是考慮該項目的好方法。
下圖顯示了.NET Core Windows Forms應用程式:
Visual Studio 2019 16.3支持創建面向.NET Core的WPF應用程式。這包括新模板以及更新的XAML設計器和XAML Hot Reload。
該設計器類似於現有的XAML設計器(以.NET Framework為目標),但是,可能會註意到體驗上的一些差異。最大的技術差異是.NET Core的設計人員使用新的錶面處理(wpfsurface.exe)僅運行針對.NET Core版本的運行時代碼。
以前.NET Framework WPF設計器進程(xdesproc.exe)本身就是承載設計器的WPF .NET Framework進程,由於運行時不相容,我們無法使用WPF .NET Framework進程(在本例中為Visual Studio) )將兩個版本的.NET(.NET Framework和.NET Core)載入到同一進程中。這意味著設計師的某些方面,像設計師擴展一樣,不能以相同的方式工作。如果正在編寫設計師擴展,我們建議閱讀XAML設計器可擴展性遷移。
下圖顯示了在新設計器中顯示的WPF應用程式:
Windows Forms設計器仍處於預覽狀態,可以單獨下載獲得。
它將作為更高版本的一部分添加到Visual Studio中。該設計器當前包括對最常用控制項和底層功能的支持。我們將通過每月更新不斷改進設計師。
我們不建議現在將Windows Forms應用程式移植到.NET Core,特別是如果依賴設計器的話。請嘗試使用設計師預覽,並給我們反饋。
還可以使用.NET CLI從命令行創建和構建桌面應用程式。
例如,可以快速創建一個新的Windows窗體應用程式:
dotnet new winforms -o myapp cd myapp dotnet run
可以使用相同的流程嘗試WPF:
dotnet new wpf -o mywpfapp cd mywpfapp dotnet run
早在2018年12月,我們就將Windows Forms和WPF開源了。很高興看到社區以及Windows Forms和WPF團隊共同努力改善這些UI框架。對於WPF,我們從GitHub存儲庫中的少量代碼開始。此時,幾乎所有WPF都已發佈到GitHub,隨著時間的流逝,還會有更多組件出現。與其他.NET Core項目一樣,這些新存儲庫是.NET Foundation的一部分,並獲得MIT許可。
所述System.Windows.Forms.DataVisualization包(包括圖表控制)也可用於.NET核心。現在,可以在.NET Core WinForms應用程式中包含此控制項。圖表控制項的源代碼可從GitHub上的dotnet / winforms-datavisualization獲得。控制項已進行了遷移,以簡化向.NET Core 3的移植,但不是我們希望對其進行重大更新的組件。
Windows本機互操作
Windows以平面C API,COM和WinRT的形式提供了豐富的本機API。自.NET Core 1.0起,我們一直支持P / Invoke,並已添加了CoCreate COM API,激活WinRT API以及將托管代碼作為COM組件作為.NET Core 3.0版本的一部分公開的功能。我們對這些功能有很多要求,因此我們知道它們會得到很多使用。
去年下半年,我們宣佈已設法從.NET Core自動化Excel。那是一個有趣的時刻。在幕後,此演示使用了COM互操作功能,例如NOPIA,對象等效性和自定義編組器。現在,可以在擴展示例中自己嘗試此演示和其他演示。
托管C ++和WinRT互操作對.NET Core 3.0具有部分支持,並將隨.NET Core 3.1一起提供。
可空引用類型
C#8.0引入了可為空的引用類型和不可為空的引用類型,使可以對引用類型變數的屬性進行重要聲明:
-
引用不應為null。當變數不應該為null時,編譯器將執行規則,以確保可以安全地取消引用這些變數,而無需先檢查其是否為null。
-
引用可以為null。當變數可能為null時,編譯器將實施不同的規則,以確保已正確檢查了null引用。
與無法從變數聲明中確定設計意圖的早期C#版本中,對引用變數的處理相比,此新功能具有明顯的優勢。通過添加可為空的引用類型,可以更清楚地聲明的意圖,並且編譯器都可以幫助正確地做到這一點併發現代碼中的錯誤。
介面成員的預設實現
如今,發佈介面後,更改介面的工作就結束了:必須在不破壞現有介面的所有實現者的情況下為其添加成員。
使用C#8.0,可以為介面成員提供主體。結果如果實現該介面的類沒有實現該成員(可能是因為在編寫代碼時還不存在該成員),那麼調用代碼將只獲得預設實現。
interface ILogger { void Log(LogLevel level, string message); void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload } class ConsoleLogger : ILogger { public void Log(LogLevel level, string message) { ... } // Log(Exception) gets default implementation }
在此示例中,ConsoleLogger該類不必實現Log(Exception)ILogger 的重載,因為它是使用預設實現聲明的。現在,只要為現有實現者提供預設實現,就可以將其添加到現有的公共介面中。
非同步流
現在foreach,可以使用來處理非同步數據流IAsyncEnumerable<T>。這個新界面正是所期望的。的非同步版本IEnumerable<T>。該語言使await foreach可以完成任務以消耗其元素。在生產方面,yield return需要生成一個非同步流。這聽起來可能有點複雜,但是在實踐中卻非常容易。
以下示例演示了非同步流的產生和使用。foreach語句是非同步的,它本身使用yield return為調用者生成非同步流。yield return建議使用此模式- 生成非同步流。
async IAsyncEnumerable<int> GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { if (result > 20) yield return result; } }
除了能await foreach,你還可以創建非同步迭代器,例如返回一個迭代器IAsyncEnumerable/ IAsyncEnumerator你既可以await和yield return英寸對於那些需要處理的對象,就可以使用IAsyncDisposable,其中各種框架類型的實現,如Stream和Timer。
指數和範圍
我們創建了新的語法和類型,可用於描述索引器,用於數組元素訪問或用於公開直接數據訪問的任何其他類型。這包括支持單個值(索引的通常定義)或兩個值(描述範圍)。
Index是描述數組索引的新類型。可以Index從一個從頭算起的int 創建一個int,或者從一個從頭算起的首碼^運算符創建一個int 。在以下示例中,可以看到兩種情況:
Index i1 = 3; // number 3 from beginning Index i2 = ^4; // number 4 from end int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"
Range相似,由兩個Index值組成,一個值用於開始,一個值用於結束,並且可以使用x..y範圍表達式編寫。然後,可以使用進行索引,Range以生成基礎數據的切片,如以下示例所示:
var slice = a[i1..i2]; // { 3, 4, 5 }
使用聲明
是否厭倦了使用要求縮進代碼的語句?不再!現在,可以編寫以下代碼,該代碼將using聲明附加到當前語句塊的作用域,然後將對象放置在它的末尾。
using System; using System.Linq; using System.Collections.Generic; using static System.Console; using System.IO; namespace usingapp { class Program { static void Main() { var filename = "Program.cs"; var line = string.Empty; var magicString = "magicString"; var file = new FileInfo(filename); using var reader = file.OpenText(); while ((line = reader.ReadLine())!= null) { if (line.Contains(magicString)) { WriteLine("Found string"); return; } } WriteLine("String not found"); } // reader disposed here } }
切換表達式
任何使用C#的人都可能喜歡switch語句的概念,而不喜歡語法。C#8引入了開關表達式,該表達式可啟用以下功能:
-
簡短語法
-
返回值,因為它是一個表達式
-
與模式匹配完全集成
switch關鍵字是“ infix”,這意味著關鍵字位於測試值(o在第一個示例中)和案例列表之間,非常類似於表達式lambdas。
第一個示例對方法使用lambda語法,該語法與switch表達式很好地集成在一起,但不是必需的。
static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point { X: var x, Y: var y } => $"({x}, {y})", _ => "unknown" };
在此示例中,有兩種模式在起作用。o首先與Point類型的模式匹配,然後與{curly braces}內的屬性模式匹配。_描述丟棄模式,它與switch語句的預設模式相同。
可以更進一步,並依靠元組的解構和參數位置,如以下示例所示:
static State ChangeState(State current, Transition transition, bool hasKey) => (current, transition) switch { (Opened, Close) => Closed, (Closed, Open) => Opened, (Closed, Lock) when hasKey => Locked, (Locked, Unlock) when hasKey => Closed, _ => throw new InvalidOperationException($"Invalid transition") };
在此示例中,可以看到不需要為每種情況定義變數或顯式類型。相反,編譯器可以將正在測試的元組與為每種情況定義的元組進行匹配。
所有這些模式使能夠編寫捕獲意圖的聲明性代碼,而不是為其執行測試的過程代碼。編譯器負責實現無聊的過程代碼,並保證始終正確執行。
在某些情況下,與兩種語法樣式都可以使用switch表達式和模式相比,switch語句將是更好的選擇。
引入快速的JSON API
.NET Core 3.0包括一個新的JSON API系列,這些系列支持讀取器/寫入器方案,使用文檔對象模型(DOM)和序列化程式的隨機訪問。可能熟悉使用Json.NET。新的API旨在滿足許多相同的場景,但是具有更少的記憶體和更快的執行速度。
可以在.NET Core 3.0中的JSON的未來中看到該計劃的最初動機和說明。其中包括Json.Net的作者James Netwon-King,他解釋了為什麼要創建新的API,而不是擴展Json.NET。簡而言之,我們想構建一個新的JSON API,以利用.NET Core中所有新的性能功能,並以此提供內聯的性能。在保持相容性的同時,不可能在像Json.NET這樣的現有代碼庫中執行此操作。
讓我們逐層快速瀏覽一下新的API。
Utf8JsonReader
System.Text.Json.Utf8JsonReader是用於從讀取的UTF-8編碼JSON文本的高性能,低分配,僅轉發讀取器ReadOnlySpan<byte>。該Utf8JsonReader是一個基礎性,低層次的類型,可以被利用來構建定製的解析器和解串器。
使用新的Utf8JsonReader讀取JSON有效負載的速度比使用Json.NET的讀取器快2倍。在需要將JSON令牌實現為(UTF16)字元串之前,它不會分配。
Utf8JsonWriter
System.Text.Json.Utf8JsonWriter提供了一個高性能的,非緩存,只進寫UTF-8從普通.NET類型編碼的JSON文本一樣的方式String,Int32和DateTime。像閱讀器一樣,編寫器是基礎的低級類型,可以利用它來構建自定義序列化程式。
使用新的寫入JSON有效負載Utf8JsonWriter比使用from Json.NET和不分配寫入器快30-80%。
JsonDocument
System.Text.Json.JsonDocument提供解析JSON數據並構建只讀文檔對象模型(DOM)的功能,可以查詢該文檔對象模型以支持隨機訪問和枚舉。
它建立在的頂部Utf8JsonReader。構成數據的JSON元素可以通過稱為的屬性JsonElement公開的類型來訪問。
該包含JSON數組和對象普查員使用API一起JSON文本普通.NET類型轉換。解析典型的JSON有效負載並使用訪問其所有成員的速度比為合理大小(即<1 MB)的數據分配很少時要快2-3倍。JsonDocumentRootElementJsonElementJsonDocumentJson.NET
JSON序列化器
System.Text.Json.JsonSerializer高性能Utf8JsonReader和Utf8JsonWriter。它從JSON反序列化對象並將對象序列化為JSON。記憶體分配保持最少,並包括對Stream非同步讀取和寫入JSON的支持。
引入新的SqlClient
SqlClient是用於通過流行的.NET O / RM(例如EF Core或Dapper)之一或直接使用ADO.NET API訪問Microsoft SQL Server和Azure SQL資料庫的數據提供程式。現在,它將作為Microsoft.Data.SqlClient NuGet包進行發佈和更新,並且受.NET Framework和.NET Core應用程式支持。通過使用NuGet,SQL團隊可以更輕鬆地為.NET Framework和.NET Core用戶提供更新。
ARM和物聯網支持
在分別在.NET Core 2.1和2.2中分別添加了對Linux和Windows的ARM32支持之後,我們在此版本中添加了對Linux ARM64的支持。儘管某些物聯網工作負載利用了我們現有的x64功能,
但許多用戶一直在尋求ARM支持。現在已經到位,我們正在與計划進行大型部署的客戶合作。
使用.NET的許多物聯網部署都是邊緣設備,並且完全面向網路。其他情況需要直接訪問硬體。在此版本中,我們增加了在Linux上使用串列埠並利用Raspberry Pi等設備上的數字引腳的功能。
引腳使用多種協議。我們增加了對GPIO,PWM,I2C和SPI的支持,以支持讀取感測器數據,與無線電交互以及將文本和圖像寫入顯示器以及許多其他情況。
.NET Core運行時前滾策略更新
現在,.NET Core運行時(實際上是運行時綁定程式)啟用了主版本前滾作為選擇策略。運行時綁定程式已將補丁和次要版本的前滾功能作為預設策略啟用。我們決定公開一組更廣泛的策略,我們認為這對各種情況都非常重要,但並未更改預設的前滾行為。
有一個名為的新屬性RollForward,該屬性接受以下值:
- LatestPatch—前滾到最高補丁程式版本。這將禁用該Minor策略。
- Minor—如果缺少所需的次要版本,則前滾到最低的次要版本。如果存在請求的次要版本,則使用該LatestPatch策略。這是預設策略。
- Major—如果缺少所需的主要版本,則前滾至最低的較高的主要版本和最低的次要版本。如果存在請求的主要版本,則使用該Minor策略。
- LatestMinor —即使存在請求的次要版本,也會前滾到最高次要版本。
- LatestMajor —即使存在要求的專業,也會前滾至最高專業和最高次要版本。
- Disable—不要前滾。僅綁定到指定版本。不建議將該策略用於一般用途,因為它會禁用前滾到最新補丁程式的功能。僅建議進行測試。
Docker和cgroup限制
許多開發人員正在使用容器打包和運行其應用程式。一個關鍵方案是限制容器的資源,例如CPU或記憶體。我們早在2017年就實現了對記憶體限制的支持。不幸的是,我們發現該實現的積極性不足以可靠地保持在配置的限制之下,並且設置了記憶體限制(尤其是<500MB)時,應用程式仍然被OOM殺死。我們已經在.NET Core 3.0中修複了該問題。鑒於此改進,我們強烈建議.NET Core Docker用戶升級到.NET Core 3.0。
Docker資源限制功能構建在cgroups之上,而cgroups是Linux內核功能。從運行時的角度來看,我們需要以cgroup原語為目標。
可以使用docker run -m參數限制容器的可用記憶體,如以下示例所示,該示例創建一個記憶體限製為4MB的基於Alpine的容器(然後列印)。
C:\>docker run -m 4mb --rm alpine cat /sys/fs/cgroup/memory/memory.limit_in_bytes
4194304
我們還添加了更改,以更好地支持CPU限制(--cpus)。這包括更改運行時間對十進位CPU值進行四捨五入的方式。如果將--cpus其值設置為接近(足夠)一個較小的整數(例如1.499999999),則運行時會將該值四捨五入(在這種情況下為1)。結果,運行時將利用少於請求數量的CPU,從而導致CPU使用率不足。通過四捨五入該值,運行時會增加OS線程調度程式的壓力,但是即使在最壞的情況下(--cpus=1.000000001—以前四捨五入為1,現在四捨五入為2),我們也沒有觀察到CPU過度使用導致性能下降的情況。降解。
下一步是確保線程池遵守CPU限制。線程池演算法的一部分是計算CPU繁忙時間,這部分是可用CPU的功能。通過在計算CPU繁忙時間時考慮CPU限制,我們避免了線程池相互競爭的各種試探法:一種嘗試分配更多的線程以增加CPU繁忙時間,另一種嘗試分配更少的線程,因為增加了更多線程不會提高吞吐量。
預設情況下減小GC堆大小
在致力於改善對docker記憶體限制的支持的同時,我們受到啟發,進行了更通用的GC策略更新,以提高更廣泛的應用程式(即使在未在容器中運行時)的記憶體使用率。這些更改使第0代分配預算更好地與現代處理器緩存大小和緩存層次結構保持一致。
Damian Edwards在我們的團隊中註意到,ASP.NET基準測試的記憶體使用量減少了一半,而對其他性能指標沒有負面影響。這是一個了不起的進步!正如他所說,這些是新的預設值,不需要更改他(或)的代碼(採用.NET Core 3.0除外)。
我們在ASP.NET基準測試中看到的記憶體節省可能或可能不代表將在應用程式中看到的內容。我們想聽聽這些更改如何減少的應用程式的記憶體使用量。
更好地支持許多proc機器
基於.NET的Windows傳統,GC需要實現Windows處理器組概念以支持具有64個以上處理器的電腦。這種實現是在5到10年前在.NET Framework中完成的。使用.NET Core,我們最初選擇了Linux PAL,以模仿相同的概念,即使Linux中不存在該概念。此後,我們在GC中放棄了這一概念,僅將其轉換為Windows PAL。
現在,GC公開了一個配置開關GCHeapAffinitizeRanges,以在具有64個以上處理器的電腦上指定相似性掩碼。Maoni Stephens在“ 使CPU數量大於64的電腦上為GC更好地配置CPU”方面寫了有關此更改的內容。
GC大頁面支持
大頁面或大頁面是一項功能,操作系統可以通過該功能建立大於本機頁面大小(通常為4K)的記憶體區域,以提高請求這些大頁面的應用程式的性能。
當發生虛擬到物理地址轉換時,首先會查詢(通常並行)稱為轉換後備緩衝區(TLB)的高速緩存,以檢查是否有可用的虛擬地址可用於所訪問的虛擬地址,以免進行潛在的昂貴操作頁表走動。每個大頁面翻譯都使用CPU內部的單個翻譯緩衝區。該緩衝區的大小通常比本地頁面大小大三個數量級;這可以提高轉換緩衝區的效率,從而可以提高頻繁訪問的記憶體的性能。在具有兩層TLB的虛擬機中,這一勝利更為重要。
現在可以使用GCLargePages選擇功能配置GC ,以選擇在Windows上分配大頁面。使用大頁面可以減少TLB遺漏,因此總體上可能會提高應用程式性能,但是,此功能有其自身的一組限制,應加以考慮。Bing嘗試了此功能,並看到了性能改進。
.NET Core版本API
我們已經改進了 .NET Core 3.0中的.NET Core版本API。他們現在返回期望的版本信息。這些更改雖然客觀上更好,但它們在技術上已被打破,並且可能會破壞依賴現有版本API來獲取各種信息的應用程式。
事件管道改進
事件管道現在支持多個會話。這意味著可以使用EventListener進程內消費事件,同時擁有進程外事件管道客戶端。
HTTP / 2支持
現在,我們在HttpClient中支持HTTP / 2。新協議是某些API的要求,例如gRPC和Apple Push Notification Service。我們希望將來有更多服務需要HTTP / 2。ASP.NET還支持HTTP / 2。
註意:首選的HTTP協議版本將通過TLS / ALPN協商,並且僅在伺服器選擇使用HTTP / 2時使用HTTP / 2。
分層編譯
分層編譯是.NET Core 2.1中的一項可選功能。此功能使運行時可以在啟動時最大程度地適應性地使用即時(JIT)編譯器,從而獲得更好的性能,並最大程度地提高吞吐量。.NET Core 3.0預設情況下啟用它。去年,我們對該功能進行了許多改進,包括對各種工作負載(包括網站,PowerShell Core和Windows桌面應用程式)進行測試。性能要好很多,這就是我們預設啟用它的原因。
IEEE浮點改進
浮點API已更新,以符合IEEE 754-2008修訂版。.NET Core浮點項目的目標是公開所有“必需的”操作,並確保它們在行為上符合IEEE規範。
.NET平臺相關的本徵
我們添加了一些API,這些API允許訪問某些面向性能的CPU指令,例如SIMD或位操作指令集。這些說明可以在某些情況下幫助實現大的性能改進,例如有效地並行處理數據。除了公開供程式使用的API之外,我們還開始使用這些說明來加速.NET庫。
以下CoreCLR PR通過實現或使用演示了一些內在函數:
-
實現簡單的SSE2硬體內在函數
-
實施SSE硬體內在函數
-
Arm64基礎硬體固有特性
-
使用TZCNT和LZCNT進行定位{第一|最後}找到{位元組|字元}
Linux上現在支持支持TLS 1.3和OpenSSL 1.1.1
NET Core現在可以利用OpenSSL 1.1.1中的TLS 1.3支持。每個OpenSSL團隊都有TLS 1.3的多項優勢:
-
由於減少了客戶端與伺服器之間的往返次數,因此縮短了連接時間
-
由於消除了各種過時和不安全的加密演算法並加密了更多的連接握手,因此提高了安全性
.NET Core 3.0能夠利用OpenSSL 1.1.1,OpenSSL 1.1.0或OpenSSL 1.0.2(在Linux系統上,無論找到哪種最佳版本)。當OpenSSL 1.1.1可用時,在使用SslProtocols時,SslStream和HttpClient類型將使用TLS 1.3。無(系統預設協議),假設客戶端和伺服器均支持TLS 1.3。
當支持變得可用時,.NET Core將在Windows和macOS上支持TLS 1.3(我們會自動期望)。
加密
我們通過和實現了對AES-GCM和AES-CCM密碼的支持。這些演算法既是帶有關聯數據的身份驗證加密(AEAD)演算法,也是添加到.NET Core的第一個身份驗證加密(AE)演算法。System.Security.Cryptography.AesGcmSystem.Security.Cryptography.AesCcm
NET Core 3.0現在支持從標準格式導入和導出非對稱公鑰和私鑰,而無需使用X.509證書。
所有密鑰類型(RSA,DSA,ECDsa,ECDiffieHellman)都支持X.509 SubjectPublicKeyInfo格式的公共密鑰,以及PKCS#8 PrivateKeyInfo和PKCS#8 EncryptedPrivateKeyInfo格式的私有密鑰。
RSA還支持PKCS#1 RSAPublicKey和PKCS#1 RSAPrivateKey。導出方法都產生DER編碼的二進位數據,而導入方法期望相同。如果密鑰以文本友好的PEM格式存儲,則調用方將需要在調用import方法之前對內容進行base64解碼。
可以使用System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo該類檢查PKCS#8文件。
可以分別使用System.Security.Cryptography.Pkcs.Pkcs12Info和檢查PFX / PKCS#12文件System.Security.Cryptography.Pkcs.Pkcs12Builder。
New Japanese Era (Reiwa)
2019年5月1日,日本開始了一個名為Reiwa的新時代。支持日語日曆的軟體(如.NET Core)必須進行更新以適應Reiwa。.NET Core和.NET Framework已更新,並且可以正確處理新時代的日文日期格式和解析。
.NET依賴操作系統或其他更新來正確處理Reiwa日期。如果或的客戶使用Windows,請下載Windows版本的最新更新。如果運行的是macOS或Linux,請下載並安裝ICU 64.2版,該版本支持新的日本時代。
在.NET博客中處理日文日曆中的新時代,可以獲得有關.NET對新日本時代的支持的更多信息。
程式集載入上下文的改進
對AssemblyLoadContext的增強:
-
啟用命名上下文
-
添加了枚舉ALC的功能
-
添加了枚舉ALC中的程式集的功能
-
使類型具體化–實例化更加容易(簡單場景不需要自定義類型)
通過AssemblyDependencyResolver與自定義一起使用AssemblyLoadContext,應用程式可以載入插件,以便從正確的位置載入每個插件的依賴項,並且一個插件的依賴項不會與另一個插件的衝突。所述AppWithPlugin樣品包括具有依賴性衝突並依靠衛星組件或本機庫插件的插件。
組件可卸性
程式集的可卸載性是AssemblyLoadContext的一項新功能。從API角度來看,此新功能在很大程度上是透明的,僅提供了一些新API。它使載入程式上下文可以卸載,從而釋放實例化類型,靜態欄位以及程式集本身的所有記憶體。應用程式應該能夠通過這種機制永久載入和卸載程式集,而不會出現記憶體泄漏。
我們希望此新功能可用於以下情況:
-
需要動態插件載入和卸載的插件方案。
-
動態編譯,運行然後刷新代碼。對於網站,腳本引擎等有用。
-
載入程式集以進行自省(例如ReflectionOnlyLoad),儘管在許多情況下MetadataLoadContext是更好的選擇。
使用MetadataLoadContext讀取程式集元數據
我們添加了MetadataLoadContext,它可以讀取程式集元數據,而不會影響調用者的應用程式域。程式集被視為數據,包括為與當前運行時環境不同的體繫結構和平臺構建的程式集。MetadataLoadContext與ReflectionOnlyLoad類型重疊,該類型僅在.NET Framework中可用。
MetdataLoadContext在System.Reflection.MetadataLoadContext包中可用。這是一個.NET Standard 2.0程式包。
MetadataLoadContext的方案包括設計時功能,構建時工具和運行時點亮功能,這些功能需要將一組程式集作為數據進行檢查,併在執行檢查後釋放所有文件鎖和記憶體。
本機托管示例
作為.NET Core 3.0的一部分,我們現在向.NET Core本機主機公開常規功能,該功能以前只能通過正式提供的.NET Core主機提供給.NET Core托管的應用程式。該功能主要與程式集載入有關。使用此功能應該可以更輕鬆地生成可以利用.NET Core完整功能集的本機主機。
其他API改進
我們的優化Span<T>,Memory<T>以及相關的.NET 2.1的核心中引入的類型。跨距構造,切片,解析和格式化等常見操作現在可以更好地執行。此外,像String之類的類型已經得到了明顯的改進,使其在Dictionary<TKey, TValue>與其他集合一起用作鍵時更加有效。無需更改任何代碼即可享受這些改進。
預設情況下,應用程式現在具有本機可執行文件
.NET Core應用程式現在使用本機可執行文件構建。這是依賴於框架的應用程式的新功能。到目前為止,只有獨立的應用程式具有可執行文件。
可以期望這些可執行文件與其他本機可執行文件具有相同的效果,例如:
可以雙擊可執行文件以啟動應用程式。
可以myapp.exe在Windows以及./myappLinux和macOS上使用,從命令提示符啟動應用程式。
作為生成的一部分生成的可執行文件將與的操作系統和CPU相匹配。例如,如果使用的是Linux x64電腦,則可執行文件將僅在該類型的電腦上運行,而不能在Windows電腦和Linux ARM電腦上運行。
這是因為可執行文件是本機代碼(就像C ++)。如果要定位其他機器類型,則需要使用運行時參數進行發佈。dotnet如果願意,可以繼續使用命令啟動應用程式,而不使用本機可執行文件。
使用ReadyToRun圖像優化.NET Core應用
通過將應用程式程式集編譯為ReadyToRun(R2R)格式,可以縮短.NET Core應用程式的啟動時間。R2R是一種提前(AOT)編譯的形式。它是.NET Core 3.0中的發佈時選擇功能。
註意:RuntimeIdentifier可以將其設置為其他操作系統或晶元。也可以在項目文件中設置。
裝配鏈接
.NET core 3.0 SDK附帶了一個工具,該工具可以通過分析IL和修剪未使用的程式集來減小應用程式的大小。這是.NET Core 3.0中的另一個發佈時選擇加入功能。
發佈單文件可執行文件
現在可以使用發佈單個文件的可執行文件dotnet publish。這種形式的單個EXE實際上是一個自解壓縮的可執行文件。它包含所有依賴項(包括本地依賴項)作為資源。在啟動時,它將所有依賴項複製到一個臨時目錄,併在該目錄中載入它們。它只需要解壓縮依賴項一次。之後,啟動很快,沒有任何損失。
可以通過將PublishSingleFile屬性添加到項目文件或在命令行上添加新的開關來啟用此發佈選項。
要生成一個獨立的單個EXE應用程式,在這種情況下,對於64位Windows:
dotnet publish -r win10-x64 /p:PublishSingleFile=true
註意:RuntimeIdentifier可以將其設置為其他操作系統或晶元。也可以在項目文件中設置。
組合修剪器,提前編譯(通過crossgen)和單個文件捆綁都是.NET Core 3.0中的所有新功能,可以一起使用,也可以單獨使用。
我們希望你們中的某些人更喜歡提前編譯器提供的單個exe,而不是我們在.NET Core 3.0中提供的自解壓可執行方法。NET 5版本將提供提前編譯器方法。
.NET 構建現在可以複製依賴項
現在,在構建操作期間,dotnet構建會將的應用程式的NuGet依賴項從NuGet緩存複製到構建輸出文件夾。在此版本之前,這些依賴項僅作為dotnet發佈的一部分進行複製。此更改使可以將構建輸出xcopy複製到其他電腦。
.NET Core工具-本地安裝
.NET Core工具已更新,可以本地安裝。與.NET Core 2.1中添加的全局工具相比,它們具有優勢。
.NET Core SDK安裝程式現在將就地升級
Windows的.NET Core SDK MSI安裝程式將開始就地升級補丁程式版本。這將減少在開發人員電腦和生產電腦上安裝的SDK的數量。
.NET Core SDK大小改進
.NET Core 3.0的.NET Core SDK明顯較小。主要原因是我們轉向了各種目的(參考程式集,框架,模板)的專用“包”,從而改變了我們構建SDK的方式。在以前的版本(包括.NET Core 2.2)中,我們從NuGet軟體包構建了SDK,其中包含許多不需要的構件,並且浪費了很多空間。
Docker發佈更新
Microsoft團隊現在正在將容器映像發佈到Microsoft Container Registry(MCR)。發生此更改的主要原因有兩個:
-
將Microsoft提供的容器映像聯合到多個註冊表,例如Docker Hub和Red Hat。
-
使用Microsoft Azure作為全局CDN,以交付Microsoft提供的容器映像。
SDK Docker映像包含PowerShell Core
註意:PowerShell Core現在作為.NET Core 3.0 SDK容器映像的一部分提供。它不是.NET Core 3.0 SDK的一部分。
紅帽支持
2015年4月,我們宣佈.NET Core將用於Red Hat Enterprise Linux。通過與Red Hat的出色工程合作,.NET Core 1.0作為組件出現在2016年6月的Red Hat軟體系列中。通過與Red Hat工程師的合作,我們已經(並將繼續學習!)有關發佈軟體的更多信息。Linux社區。
在過去的四年中,Red Hat與Microsoft在同一天發佈了許多.NET Core更新和重要版本,例如2.1和2.2。藉助.NET Core 2.2,紅帽將其.NET Core產品擴展到包括OpenShift平臺。隨著RHEL 8的發佈,我們很高興在Red Hat Application Streams中提供.NET Core 2.1以及即將推出的3.0。
總結
.NET Core 3.0是.NET Core的一個主要新版本,並且進行了大量改進。我們建議儘快開始採用.NET Core 3.0。
它通過許多方式極大地改進了.NET Core,例如大大減小了SDK的大小,並大大改善了對關鍵場景(如容器和Windows桌面應用程式)的支持。這篇文章中還沒有包括很多小的改進,隨著時間的推移,一定會從中受益。
優秀是一種習慣,歡迎大家關註學習