歡迎光臨
每天分享高質量文章

譯 | .NET Core 3.0 Preview 6 已釋出

原文:Richard Lander

翻譯:Edi Wang

今天,我們宣佈 .NET Core 3.0 Preview 6。它的更新包括編譯程式集以改進啟動、使用聯結器和 EventPipe 改進最佳化應用程式的大小。我們還在 ARM64 上釋出了針對 Alpine 的新 Docker 映象。

立即在 Windows、macOS 和 Linux 上下載 .NET Core 3.0 Preview 6。

https://dotnet.microsoft.com/download/dotnet-core/3.0

發行說明已在 dotnet/core 釋出。Preview 5 和 6 之間的 API 差異也在此處。

譯者註:

髮型說明:https://github.com/dotnet/core/blob/master/release-notes/3.0/preview/3.0.0-preview6.md

API 差異:https://github.com/dotnet/core/blob/master/release-notes/3.0/preview/api-diff/preview6/3.0-preview6.md

ASP.NET Core 以及 EF Core 今天也釋出了更新。

ASP.NET Core and Blazor updates in .NET Core 3.0 Preview 6

如果您錯過了,請檢視我們在 .NET Core 3.0 Preview 5 中釋出的改進,這些改進是從上個月開始釋出的。

WPF 及 Windows Forms 的改進

WPF 團隊現已完成將大部分 WPF 程式碼庫釋出到 GitHub。事實上,他們剛剛釋出了 15 個程式集的原始碼。對於任何熟悉 WPF 的人,程式集名稱應該非常熟悉。

在某些情況下,測試仍在在進行中,以便在 3.0 GA 之前釋出。也就是說,所有這些程式碼的存在應使 WPF 社群能夠充分參與跨 WPF 進行更改。從閱讀一些 GitHub 問題可以明顯看出,社群有自己的待辦事項,它一直在等待實現。例如,黑色主題。

Alpine Docker 映象

Docker 映象現在可用於 ARM64 上的 .NET Core 和 ASP.NET Core。它們以前僅適用於 x64。

以下映象可用於 Dockerfile docker pull,如下:

docker pull mcr.microsoft.com/dotnet/core/runtime:3.0-alpine-arm64v8

docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine-arm64v8

Event Pipe 改進

Event Pipe 現在支援多個會話。這意味著您可以使用事件偵聽器在行程中使用事件,同時具有行程外事件管道客戶端。

添加了新的 Perf 計數器:

  • % GC 時間

  • Gen 0 堆大小

  • Gen 1 堆大小

  • Gen 2 堆大小

  • LOH 堆大小

  • 分配速率

  • 已載入的程式集數量

  • 執行緒池執行緒數量

  • 監視器鎖爭用率

  • 執行緒池任務佇列

  • 執行緒池任務完成速率

探查器附加現在使用相同的 Event Pipe 基礎結構實現。

請參閱 David Fowler 的《Playing with counters》,瞭解可以使用 Event Pipe 執行自己的效能調查或僅監視應用程式狀態。

請參閱 dotnet-counters 以安裝 dotnet-counters 工具。

譯者註:

Playing with counters

https://twitter.com/davidfowl/status/1135355693634949121

dotnet-counters

https://github.com/dotnet/diagnostics/blob/master/documentation/dotnet-counters-instructions.md

使用ReadyToRun映象最佳化 .NET Core 應用

透過將應用程式程式集編譯為 ReadyToRun (R2R) 格式,可以縮短 .NET Core 應用程式的啟動時間。R2R 是提前 (AOT) 編譯的一種形式。

R2R 二進位制檔案透過減少 JIT 在應用程式載入時需要執行的工作量來提高啟動效能。二進位制檔案包含與 JIT 生成的程式碼類似的本機程式碼,在效能最重要的時候(在啟動時)給 JIT 一點假期。R2R 二進位制檔案較大,因為它們包含中間語言 (IL) 程式碼(某些方案仍然需要)和同一程式碼的本機版本,以改進啟動。

.NET Core 3.0 支援 R2R。它不能與早期版本的 .NET Core 一起使用。

樣例效能資料

以下是使用示例 WPF 應用程式收集的效能數字。該應用程式作為 self-contained 釋出,並且不使用程式集聯結器(稍後將介紹)。

譯者註:

WPF應用程式 https://github.com/ridomin/msix-catalog

僅 IL 的應用程式

啟動時間:1.9 秒

記憶體使用量: 69.1 MB

應用程式大小:150 MB

使用 ReadyToRun 映象

啟動時間:1.3 秒

記憶體使用量:55.7 MB

應用程式大小: 156 MB

ReadyToRun詳解

R2R 可以同時編譯庫和應用程式二進位制檔案。目前,庫只能作為應用程式的一部分編譯 R2R,不能作為 NuGet 包進行分發。我們希望對該方案是否重要提供更多反饋。

AOT 編譯程式集在很長一段時間內一直作為一個概念使用 .NET,可追溯到 .NET 框架和 NGEN。NGEN 有一個關鍵缺點,即必須在客戶端計算機上使用 NGEN 工具進行編譯。在應用程式構建中無法生成 NGEN 映像。

來到 .NET Core。它帶有 crossgen,它生成名為 ReadyToRun 的較新格式的原生映象。該名稱描述了其主要價值主張,即這些本機映像可以作為構建的一部分生成,並且無需在客戶端計算機上進行任何額外的工作即可”準備執行”。這是一個重大進步,也是風向變化的重要勝利。

在相容性方面,ReadyToRun 映象與 IL 程式集類似,存在一些關鍵差異。

IL 程式集僅包含 IL 程式碼。它們可以在支援該程式集的給定標的框架的任何執行時上執行。例如,netstandard2.0 程式集可以在任何受支援的作業系統(Windows、macOS、Linux)和體系結構(英特爾、ARM、32 位、64 位)上執行.NET Framework 4.6+ 和 .NET Core 2.0+。

R2R 程式集包含 IL 和本機程式碼。它們為特定的最小化 .NET Core 執行時版本和執行時環境 (RID) 編譯。例如 .NET Standard 2.0 程式集可能是為 .NET Core 3.0 和 Linux x64 編譯的 R2R。它僅在該配置或相容配置(如 .NET Core 3.1 或 .NET Core 5.0,在 Linux x64 上)中可用,因為它包含僅在該執行時環境中可用的本機程式碼。

指示

ReadyToRun 編譯是僅釋出、選擇加入的功能。我們和.NET Core 3.0 Preview 5一起釋出了其預覽版本。

要啟用 ReadyToRun 編譯,您必須:

  • 將 PublishReadyToRun 屬性設定為 true。

  • 使用顯式 RuntimeIdentifier 釋出。

註意: 編譯應用程式程式集時,生成的本機程式碼特定於平臺和體系結構(這就是為什麼在釋出時必須指定有效的執行時識別符號)。

下麵是一個示例:

    Exe

    netcoreapp3.0

    true

並使用以下命令釋出:

dotnet publish -r win-x64 -c Release

註意:也可以在專案檔案中設定RuntimeIdentifier。

註意: ReadyToRun 目前僅支援自包含(self-contained)應用。它將在以後的預覽中為依賴於框架的應用啟用。

透過將”PublishReadyToRunEmitSymbols“屬性設定為 true,可以在專案中啟用本機Symbol生成。不需要為除錯目的生成本機Symbol。這些Symbol僅用於分析目的。

SDK 當前支援一種將某些程式集編譯為 ReadyToRun 映像的方法。當某些程式集實際上不需要針對效能進行最佳化時,這可能很有用。這可以幫助減小應用程式的大小。對於 ReadyToRun 編譯器無法編譯特定程式集的情況,它也可以是一種有用的解決方法。使用”PublishReadyToRunExclude“項組完成排除。例子:

跨平臺/架構編譯

ReadyToRun 編譯器當前不支援交叉定位。您需要在給定標的上編譯。例如,如果希望 Windows x64 的 R2R 映象,則需要在該環境中執行釋出命令。

例外情況:

Windows x64 可用於編譯 Windows ARM32、ARM64 和 x86 映象。

Windows x86 可用於編譯 Windows ARM32 映象。

Linux x64 可用於編譯 Linux ARM32 和 ARM64 映象。

程式集連結

.NET Core 3.0 SDK 附帶了一個工具,可以透過分析 IL 和修剪未使用的程式集來減小應用的大小。

使用 .NET Core,始終可以釋出包含執行程式碼所需的一切的自包含應用,而無需在部署標的上安裝 .NET。在某些情況下,應用只需要框架的一小部分才能執行,並且可能透過僅包含已使用的庫而縮小。

我們使用 IL 聯結器掃描應用程式的 IL 以檢測實際需要的程式碼,然後修剪未使用的框架庫。這可以顯著減小某些應用的大小。通常,類似工具的小型控制檯應用受益最大,因為它們傾向於使用框架的較小子集,並且通常更便於修剪。

要使用此工具,請在專案中設定 PublishTrimmed=true,併在專案中釋出自包含(self-contained)的應用:

dotnet publish -r -c Release

釋出輸出將包括框架庫的子集,具體取決於應用程式程式碼呼叫的內容。對於 helloworld 應用,聯結器將大小從 +68MB 減少到 28MB。

使用反射或相關動態功能的應用程式或框架(包括 ASP.NET Core 和 WPF)在修剪時通常會中斷,因為聯結器不知道此動態行為,通常無法確定哪些框架型別在執行時進行反射所需的。要修剪此類應用,您需要告訴聯結器程式碼中反射以及所依賴的任何包或框架中所需的任何型別。請務必在修剪後測試應用。

有關 IL 聯結器的詳細資訊,請參閱檔案,或訪問單mono/linker倉庫。

譯者註:

檔案:https://aka.ms/dotnet-illink

倉庫:https://github.com/mono/linker

註意:在 .NET Core 的早期版本中,ILLink.Tasks 作為外部 NuGet 包提供,並提供了許多相同的功能。它不再受支援 – 請更新到最新的 3.0 SDK 並嘗試新的體驗!

將聯結器和ReadToRun一起用

聯結器和 ReadyToRun 編譯器可用於同一應用程式。通常,聯結器會使應用程式變小,然後隨時執行的編譯器會使其再次變大一點,但效能會顯著提高。值得在各種配置中進行測試,以瞭解每個選項的影響。

註意: dotnet/sdk #3257阻止聯結器和 ReadyToRun 一起使用到 WPF 和 Windows Forms 應用程式。我們正在努力修複它作為 .NET Core 3.0 版本的一部分。

原生託管示例

團隊最近釋出了原生託管示例。它演示了在原生應用程式中託管 .NET Core 的最佳做法方法。

作為 .NET Core 3.0 的一部分,我們現在向 .NET Core 原生託管公開常規功能,這些託管以前僅透過官方提供的 .NET Core 託管對 .NET Core 託管應用程式可用。該功能主要與程式集載入相關。此功能應使生成原生託管變得更容易,這些原生託管可以利用 .NET Core 的完整功能集。

譯者註:

示例 

https://github.com/dotnet/samples/tree/master/core/hosting/HostWithHostFxr

HttpClient的HTTP/2支援

HTTP/2 是 HTTP 協議的主要修訂版。HTTP/2 的一些顯著功能是支援標頭壓縮和透過同一連線完全多路復用流。雖然 HTTP/2 保留了 HTTP 的語意(HTTP 標頭、方法等),但它在資料框架和透過無線方式傳送方面與 HTTP/1.x 是一種變化。

HttpClient 現在新增用於發出 HTTP/2 請求的支援。當預設值仍為 HTTP/1.1 時,您可以透過在 HTTP 請求訊息上設定版本來選擇使用 HTTP/2。

var client = new HttpClient() { BaseAddress = new Uri(“https://localhost:5001”) };

// HTTP/1.1 request

using (var response = await client.GetAsync(“/”))

{

    Console.WriteLine(response.Content);

}

// HTTP/2 request

using (var request = new HttpRequestMessage(HttpMethod.Get, “/”) { Version = new Version(2, 0) })

using (var response = await client.SendAsync(request))

{

    Console.WriteLine(response.Content);

}

或者,您可以透過在 HttpClient 上設定預設請求版本屬性來預設傳送 HTTP/2 請求。

var client = new HttpClient()

{

    BaseAddress = new Uri(“https://localhost:5001”),

    DefaultRequestVersion = new Version(2, 0)

};

// Defaults to HTTP/2

using (var response = await client.GetAsync(“/”))

{

    Console.WriteLine(response.Content);

}

由於框架的這種更改,伺服器和客戶端需要協商所使用的協議版本。應用程式層協議協商 (ALPN) 是一個 TLS 擴充套件,允許伺服器和客戶端協商作為 TLS 握手的一部分使用的協議版本。雖然伺服器和客戶端之間有可能在協議上事先知道,但大多數伺服器僅支援 ALPN 作為建立 HTTP/2 連線的唯一方法。因此,HTTP/2 僅在 TLS 連線上由 HttpClient 協商。

在開發方案中,當伺服器和客戶端事先知道兩者都講 HTTP/2 未加密時,您可以透過設定 AppContext 開關或環境變數(DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1)在明文上建立 HTTP/2 連線。

AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport”, true);

尾聲

請嘗試新功能。請提交你發現的錯誤,問題或任何具有挑戰性的經驗。我們需要反饋!您也可以提交功能請求,但它們可能需要等待實現,直到此時的下一個版本。

現在,我們非常接近於完成 .NET Core 3.0 的功能,並且正在將團隊的重點轉移到釋出的質量上。我們還有幾個月的錯誤修複和效能工作。當我們完成這一過程時,我們也會感謝您的反饋。

請註意,我們將很快將 .NET Core 儲存庫的主分支切換到下一個主要版本,很可能在預覽 7 釋出(7 月)釋出或之後。

感謝您嘗試 .NET Core 3.0 預覽版。我們感謝您的幫助。此時,我們專註於獲得最終版本。

贊(0)

分享創造快樂