我們很高興可以發佈 .NET Core 2.1。這次更新包括對性能的改進,對運行時和工具的改進。還包含一種以 NuGet 包的形式部署工具的新方法。我們添加了一個名為 [`Span ...
我們很高興可以發佈 .NET Core 2.1。這次更新包括對性能的改進,對運行時和工具的改進。還包含一種以 NuGet 包的形式部署工具的新方法。我們添加了一個名為 Span<T>
的新基元類型,它可以在沒有記憶體分配的情況下對數據進行操作。還有許多其他新的 API,專註於密碼學,壓縮和 Windows 相容性。它是第一個支持 Alpine Linux 和 ARM32 晶元的版本。您今天就可以開始將現有項目更新至 .NET Core 2.1 了。 該版本與 .NET Core 2.0 相容,更新會變得很簡單。
ASP.NET Core 2.1 和 Entity Framework Core 2.1 也已在今天發佈。
您可以在 Windows,MacOS 和 Linux 上下載並開始使用 .NET Core 2.1:
- .NET Core 2.1 SDK (includes the runtime)
- .NET Core 2.1 Runtime
.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增量式構建時性能改進。註意:圖中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 sockets 和 Span
SocketsHttpHandler 現在是 HttpClient 的預設實現。 SocketsHttpHandler 最大的勝利就是性能。它比現有的實現快得多。它還消除了特定於平臺的依賴關係,並支持跨操作系統的一致行為。
有關如何啟用舊網路堆棧的說明,請參閱 .NET Core 2.1發行說明。
Span, Memory, and friends
我們正在進入一個使用 .NET 進行記憶體高效計算的新時代,引入 Span
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 APIs — System.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 class — CryptographicOperations.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臨時版本所取得的進展:RC1,Preview 2,Preview 1。再次感謝所有為此發佈做出貢獻的人。