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

譯 | .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)

分享創造快樂