[翻譯] .NET Core 2.1 發布


原文: Announcing .NET Core 2.1

我們很高興可以發布 .NET Core 2.1。這次更新包括對性能的改進,對運行時和工具的改進。還包含一種以 NuGet 包的形式部署工具的新方法。我們添加了一個名為 Span<T> 的新基元類型,它可以在沒有內存分配的情況下對數據進行操作。還有許多其他新的 API,專注於密碼學,壓縮和 Windows 兼容性。它是第一個支持 Alpine Linux 和 ARM32 芯片的版本。您今天就可以開始將現有項目更新至 .NET Core 2.1 了。 該版本與 .NET Core 2.0 兼容,更新會變得很簡單。

ASP.NET Core 2.1Entity Framework Core 2.1 也已在今天發布。

您可以在 Windows,MacOS 和 Linux 上下載並開始使用 .NET Core 2.1:

.NET Core 和 ASP.NET Core 的 Docker 鏡像也已經可用: microsoft/dotnet

本月早些時候召開了 Build 2018 大會。我們對 .NET Core 進行了幾次深入的演示。可以在 Channel9 上查看 Build 2018 sessions for .NET

您可以在 .NET Core 2.1 發行說明 中看到該發行版的完整詳細信息。發行說明中包含相關說明、已知問題和解決方法。請在評論中或dotnet/core #1614 中提交您發現的任何問題

感謝為 .NET Core 2.1 做出貢獻的每個人。您已經幫助 .NET Core 成為更好的產品!

Long-term Support 長期支持

.NET Core 2.1 將是一個長期支持(LTS)版本。這意味着它會支持三年。我們建議您將 .NET Core 2.1 作為 .NET Core 開發的新標准。

我們打算在未來 2-3 個月內發布少量重要更新,然后正式將 .NET Core 2.1 作為 LTS 發布。之后,更新將針對安全性、可靠性以及添加平台支持(例如 Ubuntu 18.10)。我們建議您現在開始采用 .NET Core 2.1。對於處於活躍開發狀態的應用程序,沒有理由推遲將 .NET Core 2.1 部署到生產環境中。對於不活躍開發狀態的應用程序,我們建議您等待部署,直到將 .NET Core 2.1 聲明為 LTS。

有以下幾個原因升級到 .NET Core 2.1:

  • 長期支持(LTS)。
  • 卓越的性能和質量。
  • 新的平台支持,例如:Ubuntu 18.04,Alpine,ARM32。
  • 更容易的在項目文件中管理平台依賴關系和自包含應用程序發布。

我們收到很多希望將 .NET Core 2.0 作為 LTS 版本的請求。事實上,那是我們原來的計划。我們選擇等待,直到我們解決了管理平台依賴性的各種挑戰(上面的最后一點)。平台依賴管理是 .NET Core 1.0 中的一個重要問題,並且隨着每個版本的逐步改進。例如,您會注意到 ASP.NET Core 軟件包引用不再包含 .NET Core 2.1 的版本號。

Platform Support 平台支持

.NET Core 2.1 支持以下操作系統:

  • Windows Client: 7, 8.1, 10 (1607+)
  • Windows Server: 2008 R2 SP1+
  • macOS: 10.12+
  • RHEL: 6+
  • Fedora: 26+
  • Ubuntu: 14.04+
  • Debian: 8+
  • SLES: 12+
  • openSUSE: 42.3+
  • Alpine: 3.7+

芯片支持如下:

  • Windows,MacOS 和 Linux上 的 x64
  • Windows 上的 x86
  • Linux 上的 ARM32(Ubuntu 18.04+,Debian 9+)

注意:Raspberry Pi 2+ 支持 .NET Core 2.1。 它在 Pi Zero 或其他使用 ARMv6 芯片的設備上不受支持。.NET Core 需要 ARMv7 或 ARMv8 芯片,如 ARM Cortex-A53。

.NET Core Tools 工具

.NET Core tools 現在有一個新的部署和擴展機制。這種新體驗與 NPM 全局工具非常相似,同時受到 NPM 的啟發。您可以通過查看 dotnetsay tools 示例 來創建自己的全局 tools 。

您可以使用以下命令嘗試使用 dotnetsay

dotnet tool install -g dotnetsay
dotnetsay

.NET Core tools 是一個 .NET Core 控制台應用程序,它們是作為 NuGet 包來打包和獲取的。默認情況下,這些 tools 是依賴於框架的應用程序,並包含其所有的 NuGet 依賴項。這意味着 .NET Core tools 默認運行在所有支持 .NET Core 的操作系統和芯片架構上,並帶有一組二進制文件。默認情況下,dotnet tool install 命令會在 NuGet.org 上查找 tools 。您也可以改用您自己的 NuGet Feed。

目前,.NET Core Tools 僅支持全局安裝且需要 -g 參數。我們也在開展各種形式的本地安裝,並計划在后續版本中提供。

我們期望一個全新的 tools 生態系統能夠為它自身服務。 @natemcmaster 維護了一個 dotnet tools 列表。你也可以看看他的 dotnet-serve 工具。

以下現有的 DotNetCliReferenceTool tools 已被轉換為內置 tools。

  • dotnet watch
  • dotnet dev-certs
  • dotnet user-secrets
  • dotnet sql-cache
  • dotnet ef

升級到 .NET Core 2.1 時,請除去這些 tools 的項目引用。

Build Performance Improvements 構建性能優化

提高 .NET Core 構建的性能可能是該版本的最大焦點。 它在 .NET Core 2.1 中有了很大改進,特別是對於增量構建。這些改進適用於命令行上的 dotnet build 和 Visual Studio 中的構建。

與 .NET Core 2.0 相比,下圖顯示了我們所做的改進。我們專注於大型項目,正如您從圖像中看到的那樣。

.NET Core 2.1 Incremental Build-time performance improvements
(圖:.NET Core 2.1增量式構建時性能改進。注意:圖中2.1是指2.1.300 SDK版本。)
(注:這些測試數據來自 mikeharder/dotnet-cli-perf 項目。)

我們將長期運行的服務器添加到 .NET Core SDK 中,以提高常見開發操作的性能。這些服務器附加了進程運行時間超過單個 dotnet 構建調用。其中一些是遷移自 .NET Framework,另一些是全新的。

已添加以下 SDK 構建服務器:

  • VBCSCompiler
  • MSBuild worker processes
  • Razor server

這些服務器的主要優點是它們跳過了在每個 dotnet 構建調用中 JIT 編譯大塊代碼的需要。它們會在一段時間后自動終止。有關更好地控制這些構建服務器的更多信息,請參閱發行說明

Runtime Performance Improvements 運行時性能優化

請參閱.NET Core 2.1中的性能改進一文,以深入了解該版本中的所有性能改進。

Networking Performance Improvements 網絡性能優化

我們構建了一個名為 SocketHttpHandler 的全新從頭開始的 HttpClientHandler 以提高網絡性能。它是基於 .NET socketsSpan HttpClient 的 C# 實現。

SocketsHttpHandler 現在是 HttpClient 的默認實現。 SocketsHttpHandler 最大的勝利就是性能。它比現有的實現快得多。它還消除了特定於平台的依賴關系,並支持跨操作系統的一致行為。

有關如何啟用舊網絡堆棧的說明,請參閱 .NET Core 2.1發行說明

Span , Memory , and friends

我們正在進入一個使用 .NET 進行內存高效計算的新時代,引入 Span 及相關類型。今天,如果您想要傳遞 10,000 元素數組中的前 1000 個元素,則需要復制這 1000 個元素並將該副本傳遞給調用者。這種操作在時間和空間上都很昂貴。新的 Span 類型使您可以提供該陣列的虛擬視圖,而無需時間或空間成本。 Span 是一個結構體,這意味着您可以在不分配的情況下啟用分析或其他計算的復雜流水線。出於這個原因,我們在 corefx 中廣泛使用這種新類型。

Jared Parsons 在他的 Channel 9 video C# 7.2: Understanding Span 中給出了很好的介紹。 Stephen Toub 也有一篇文章介紹這些 C# – All About Span: Exploring a New .NET Mainstay

在最簡單的用例中,您可以將一個數組轉換為Span ,如下所示。

var arr = new byte[10];
Span<byte> bytes = arr; // Implicit cast from T[] to Span<T>

您可以Slice 一個 Span ,如下所示。

// generating data for the example
int[] ints = new int[100];
for (var i = 0; i < ints.Length; i++)
{
    ints[i] = i;
}
// creating span of array
Span<int> spanInts = ints;
// slicing the span, which creates another (subset) span
Span<int> slicedInts = spanInts.Slice(start: 42, length: 2);
// printing composition of the array and two spans
Console.WriteLine($"ints length: {ints.Length}");
Console.WriteLine($"spanInts length: {spanInts.Length}");
Console.WriteLine($"slicedInts length: {slicedInts.Length}");
Console.WriteLine("slicedInts contents");
for (var i = 0; i < slicedInts.Length; i++)
{
    Console.WriteLine(slicedInts[i]);
}
// performing tests to validate the span has the expected contents
if (slicedInts[0] != 42) Console.WriteLine("error");
if (slicedInts[1] != 43) Console.WriteLine("error");
slicedInts[0] = 21300;
if (slicedInts[0] != ints[42]) Console.WriteLine("error");
// printing composition of subset span
Console.WriteLine("slicedInts contents");
for (var i = 0; i < slicedInts.Length; i++)
{
    Console.WriteLine(slicedInts[i]);
}

這些代碼產生如下輸出:

ints length: 100
spanInts length: 100
slicedInts length: 2
slicedInts contents
42
43
slicedInts contents
21300
43

Brotli Compression Brotli 壓縮

Brotli 是一種通用的無損壓縮算法,壓縮數據可與當前最好的通用壓縮方法相媲美。速度與 deflate 相似,但提供更強力的壓縮。Brotli 壓縮數據格式的規范在 RFC 7932 中定義。大多數 Web 瀏覽器,主要 Web 服務器和一些 CDN(Content Delivery Networks)都支持 Brotli 編碼。.NET Core Brotli 實現基於 Google 在 google/brotli 上提供的c代碼。謝謝,谷歌!

Brotli 支持 已被添加到 .NET Core 2.1 中。操作可以使用基於流的 BrotliStream 或基於高性能跨度的 BrotliEncoder/BrotliDecoder 類來完成。你可以看到它在下面的例子中使用。

using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Threading.Tasks;
using static System.Console;

namespace BrotliApp
{
    class Program
    {
        static readonly string s_URL = "https://raw.githubusercontent.com/dotnet/core/master/README.md";
        static async Task Main(string[] args)
        {
            var client = new HttpClient();
            var response = await client.GetAsync(s_URL,HttpCompletionOption.ResponseHeadersRead);
            var stream = await response.Content.ReadAsStreamAsync();

            WriteLine($"Request URL: {s_URL}");
            WriteLine($"Initial content length: {response.Content.Headers.ContentLength}");
            var compressedStream = CompressWithBrotli(stream);
            WriteLine($"Compressed content length: {compressedStream.Length}");
            var decompressedStream = DecompressWithBrotli(compressedStream);
            WriteLine($"Decompressed content length: {decompressedStream.Length}");
            WriteLine($"Compression ratio: {100 - (Decimal.Divide(compressedStream.Length, response.Content.Headers.ContentLength.Value)*100):N1}%");
            WriteLine("First 10 lines of decompressed content");
            WriteLine();

            var reader = new StreamReader(decompressedStream);
            for (var i = 0; i < 10; i++)
            {
                WriteLine(reader.ReadLine());
            }
        }

        public static Stream CompressWithBrotli(Stream toCompress)
        {
            MemoryStream compressedStream = new MemoryStream();
            using (BrotliStream compressionStream = new BrotliStream(compressedStream, CompressionMode.Compress, leaveOpen: true))
            {
                toCompress.CopyTo(compressionStream);
            }
            compressedStream.Position = 0;
            return compressedStream;
        }

        public static Stream DecompressWithBrotli(Stream toDecompress)
        {
            MemoryStream decompressedStream = new MemoryStream();
            using (BrotliStream decompressionStream = new BrotliStream(toDecompress, CompressionMode.Decompress, leaveOpen: true))
            {
                decompressionStream.CopyTo(decompressedStream);
            }
            decompressedStream.Position = 0;
            return decompressedStream;
        }
    }
}

該代碼產生以下輸出:

Request URL: https://raw.githubusercontent.com/dotnet/core/master/README.md
Initial content length: 2244
Compressed content length: 727
Decompressed content length: 2244
Compression ratio: 67.6%
First 10 lines of decompressed content

# .NET Core Home
The dotnet/core repository is a good starting point for .NET Core.
The latest major release is [.NET Core 2.1](release-notes/2.1/2.1.0.md). The latest patch updates are listed in [.NET Core release notes](release-notes/README.md)
## Download the latest .NET Core SDK
* [.NET Core 2.1 SDK](release-notes/download-archives/2.1.0-download.md)

New Cryptography APIs 新的密碼學API

.NET Core 密碼學 API 已進行了以下增強:

  • New SignedCms APIsSystem.Security.Cryptography.Pkcs.SignedCms is now available in the System.Security.Cryptography.Pkcspackage. The .NET Core implementation is available to all .NET Core platforms and has parity with the class from .NET Framework. See: dotnet/corefx #14197.
  • New X509Certificate.GetCertHash overload for SHA-2 — New overloads for X509Certificate.GetCertHash and X509Certificate.GetCertHashString accept a hash algorithm identifier to enable callers to get certificate thumbprint values using algorithms other than SHA-1. dotnet/corefx #16493.
  • New Span -based cryptography APIs — Span-based APIs are available for hashing, HMAC, (cryptographic) random number generation, asymmetric signature generation, asymmetric signature processing, and RSA encryption.
  • Rfc2898DeriveBytes performance improvements — The implementation of Rfc2898DeriveBytes (PBKDF2) is about 15% faster, based on using Span -based . Users who benchmarked an iteration count for an amount of server time may want to update iteration count accordingly.
  • Added CryptographicOperations classCryptographicOperations.FixedTimeEquals takes a fixed amount of time to return for any two inputs of the same length, making it suitable for use in cryptographic verification to avoid contributing to timing side-channel information. CryptographicOperations.ZeroMemory is a memory clearing routine that cannot be optimized away via a write-without-subsequent-read optimization.
  • Added static RandomNumberGenerator.Fill — The static RandomNumberGenerator.Fill will fill a Span with random values using the system-preferred CSPRNG, and does not require the caller to manage the lifetime of an IDisposable resource.
  • Added support for RFC 3161 cryptographic timestamps — New API to request, read, validate, and create TimestampToken values as defined by RFC 3161.
  • Add Unix EnvelopedCms — The EnvelopedCms class has been added for Linux and macOS.
  • Added ECDiffieHellman — Elliptic-Curve Diffie-Hellman (ECDH) is now available on .NET Core via the ECDiffieHellman class family with the same surface area as .NET Framework 4.7.
  • Added RSA-OAEP-SHA2 and RSA-PSS to Unix platforms — Starting with .NET Core 2.1 the instance provided by RSA.Create() can always encrypt or decrypt with OAEP using a SHA-2 digest, as well as generate or validate signatures using RSA-PSS

Windows Compatibility Pack

將現有代碼從 .NET Framework 移植到 .NET Core 時,可以使用 Windows Compatibility Pack。它提供了額外的 20,000 個API,與 .NET Core 中可用的 API 相比。這包括System.Drawing,EventLog,WMI,性能計數器和 Windows 服務。有關更多信息,請參閱Announcing the Windows Compatibility Pack for .NET Core

以下示例演示使用 Windows Compatibility Pack 提供的 API 訪問 Windows 注冊表。

rivate static string GetLoggingPath()
{
    // Verify the code is running on Windows.
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam\AssetManagement"))
        {
            if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
                return configuredPath;
        }
    }

    // This is either not running on Windows or no logging path was configured,
    // so just use the path for non-roaming user-specific data files.
    var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    return Path.Combine(appDataPath, "Fabrikam", "AssetManagement", "Logging");
}

Tiered Compilation 分層編譯

我們為運行時添加了一個新的令人興奮的功能預覽,稱為分層編譯。這是運行時更適應性地使用Just-In-Time(JIT)編譯器以獲得更好性能的一種方式。

JIT 編譯器的基本挑戰是編譯時間是應用程序執行時間的一部分。生成更好的代碼通常意味着花更多的時間來優化它。但是如果一段代碼只執行一次或幾次,編譯器可能會花費更多時間優化它,而不是僅僅運行未優化版本。

通過分層編譯,編譯器首先盡可能快地生成代碼,只需最少的優化(第一層)。然后,當它檢測到某些方法執行了很多時,它會生成這些方法(第二層)的更優化版本,然后用它們代替。第二層編譯是並行執行的,這消除了快速編譯速度和生成最優代碼之間的矛盾。這個模型可以更一般地稱為自適應優化

分層編譯對長時間運行的應用程序(如Web服務器)也有好處。我們將在后續章節中詳細介紹,但簡短的版本是JIT可以生成比我們為 .NET Core 本身提供的預編譯程序集更好的代碼。這主要是由於fragile binary interface 問題。通過分層編譯,JIT 可以使用它為 .NET Core 找到的預編譯代碼,然后為需要調用的方法編譯更好的代碼。我們已經看到這種情況對我們的性能實驗室中的測試有很大的影響。

您可以通過設置環境變量來測試分層編譯:

COMPlus_TieredCompilation="1"

您可以通過設置 TieredCompilation 屬性為應用程序啟用分層編譯,如您在這個項目中所看到的。

Self-contained application publishing 自包含的應用程序發布

dotnet publish 現在發布帶有服務運行時版本的self-contained applications。當您使用新 SDK 發布自包含應用程序時,您的應用程序將包含該 SDK 已知的最新服務運行時版本。當您升級到最新的 SDK 時,您將使用最新的 .NET Core 運行時版本進行發布。這適用於 .NET Core 1.0 運行時和更高版本。

自包含發布依賴於 NuGet.org 上的運行時版本。你不需要在你的機器上有服務運行時。

除非通過 RuntimeFrameworkVersion 屬性指定了不同的版本,否則使用 .NET Core 2.0 SDK,自包含應用程序將與 .NET Core 2.0.0 Runtime 一起發布。有了這種新行為,您將不再需要設置此屬性來為自包含應用程序選擇更高的運行時版本。最簡單的方法是始終使用最新的 SDK 進行安裝和發布。

Docker

Docker Hub上 的 microsoft/dotnet 提供了用於 .NET Core 2.1 的 Docker 鏡像。我們已經做了一些相對於 .NET Core 2.0 的更改。我們已經整合了用於 .NET Core和 ASP.NET Core 的 Docker Hub 存儲庫集合。我們將使用 microsoft/dotnet 作為我們為 .NET Core 2.1 及更高版本發布的唯一存儲庫。

我們向 .NET Core 鏡像添加了一組環境變量,以便在任何 .NET Core 鏡像層托管 ASP.NET Core站點,並在 SDK 容器鏡像中啟用 dotnet watch 而無需其他配置。

.NET Core Docker 示例 已移至 dotnet/dotnet-docker 庫。 這些示例已針對 .NET Core 2.1 進行了更新。已添加新示例,包括通過 HTTPS 托管 ASP.NET Core Docker 鏡像

有關更多信息,請參見.NET Core 2.1 Docker 鏡像更新

.NET Core 2.1 和兼容性

.NET Core 2.1 是一個高度兼容的版本。在沒有安裝 .NET Core 2.0 的情況下,.NET Core 2.0應用程序將在 .NET Core 2.1 上運行。這種前滾行為僅適用於次要版本, .NET Core 1.1 不會前滾到 2.0,.NET Core 2.0 也不會前滾到 3.0。

有關如何禁用次要版本前滾的說明,請參閱.NET Core 2.1發行說明

如果您使用 .NET Core 2.1 預覽版建立 .NET Core 2.1 應用程序或工具,則必須使用最終的 .NET Core 2.1 版本進行重建。預覽版本不會前滾到最終版本。

Early Snap Installer Support 早期的 Snap 安裝程序支持

我們一直致力於將 .NET Core 引入 Snap ,並准備好聽取您的想法。 Snaps 以及其他一些技術,是我們認為很有趣的新興應用程序安裝和沙盒技術。Snap 安裝適用於基於 Debian 的系統和其他發行版,例如 Fedora 正面臨着我們正在努力解決的挑戰。如果您想嘗試一下,可以使用以下步驟。

.NET Core 2.1 運行時 和 SDK 的 Snap 可用:

  • sudo snap install dotnet-sdk --candidate --classic
  • sudo snap install dotnet-runtime-21 --candidate

留意未來的文章,探討 Snaps 的內容。與此同時,我們很樂意聽取您的反饋意見。

Closing 尾聲

.NET Core 2.1 是該平台的一大進步。我們已經大幅改進了性能,添加了許多API,並增加了部署 tools 的新方法。我們還增加了對新的 Linux 發行版和另一種 CPU 類型 ARM32 的支持。此版本擴展了您可以使用 .NET Core 的地方,並使其在各處更加高效。

我們預計 .NET Core 2.1 將在本周晚些時候在 Azure App Service 中提供。

您可以看到我們使用.NET Core 2.1臨時版本所取得的進展:RC1Preview 2Preview 1。再次感謝所有為此發布做出貢獻的人。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM