1. 程式人生 > >譯 .NET Core 3.0 釋出

譯 .NET Core 3.0 釋出

原文:《Announcing .NET Core 3.0》

宣佈.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的事情,現在直播(https://www.dotnetconf.net/)!

可以下載適用於Windows,macOS和Linux的.NET Core 3.0:

  • .NET Core 3.0 SDK和執行時 

  • 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桌面應用程式)的支援。這篇文章中還沒有包括很多小的改進,隨著時間的推移,一定會從中受益。

 

優秀是一種習慣,歡迎大家關注學習