官宣 .NET 7 預覽版3

微軟技術棧發表於2022-05-13

很高興地宣佈,我們釋出了.NET 7 預覽版3。.NET 7的第三個預覽版包括了對可觀察性、啟動時間、codegen、GC regions、本地AOT編譯等方面的增強。您現在就可以獲取並開始嘗試新功能,包括:

  • 原生 AOT
  • 預設 GC regions
  • ASP.NET Core 啟動時間改進

您可以下載適用於 Windows、macOS 和 Linux 的 .NET 7 預覽版 3。

.NET 7預覽版3已經在Visual Studio 17.2預覽版3中進行了測試。如果您想嘗試 .NET 7和Visual Studio的系列產品,我們建議您使用預覽版。Mac版的Visual Studio暫時還未支援.NET 7預覽版,但很快就會發布。現在,讓我們瞭解這個版本中的一些最新更新的內容。

更快、更輕量級的原生AOT應用

.NET 7 預覽版2的部落格文章中,我們宣佈原生AOT專案已經從實驗狀態轉移到.NET /runtime repo的.NET 7的主線開發中。我們知道您們中的許多人都在急切地等待著來自團隊的關於Native AOT的更新,我們在預覽版3中有一些新的更新。

如果您想了解原生AOT的詳細資訊,或者想要開始使用它,repo文件是最好的選擇。

我們也意識到您們中的一些人可能不熟悉原生 AOT是什麼,所以我們想分享它的一個快速概述給您們。

▌什麼是原生AOT?

提前編譯(AOT)是指在應用程式構建時(而不是執行時)生成程式碼的一系列技術。AOT 對 .NET 來說並不陌生。今天我們釋出了用於客戶端和伺服器場景的ReadyToRun,以及用於移動和WASM的Mono AOT。原生AOT為.NET桌面客戶端和伺服器場景帶來了完整的原生預編譯。原生AOT並沒有取代這些現有技術,而是提供了一組新的功能,可以解鎖新的form factors。
現有的AOT編譯的.NET程式集包含特定於平臺的資料結構和原生程式碼,用於通常在執行時完成的前置載入工作。預編譯這些工件可以節省啟動時的時間(例如ReadyToRun),並允許訪問非JIT平臺(例如iOS)。如果沒法做預先編譯,.NET要麼退回到JIT,要麼退回到解釋(取決於平臺)。

原生AOT類似於.NET現有的AOT技術,但它只生成原生artifacts。事實上,本機AOT執行時並不知道如何讀取 .NET程式集檔案格式—所有這些都是平臺本機的。可執行檔案格式解析完全由底層作業系統處理。

原生AOT的主要優點是在啟動時間、記憶體使用、訪問受限平臺(不允許JIT)和更小的磁碟大小方面。當作業系統將應用程式中的頁面放入記憶體時,應用程式就開始執行。資料結構是為了執行AOT生成的程式碼而優化的,而不是為了在執行時編譯新程式碼。這類似於Go、Swift和Rust等語言的編譯方式。原生AOT最適合哪些非常看重啟動時間的環境。針對原生AOT的要求比一般的.NET Core/5+應用程式和庫更嚴格。原生AOT禁止在執行時emit新程式碼(例如Reflection.Emit),也禁止在執行時載入新的 .NET程式集(例如外掛模型)。

▌為原生AOT準備應用程式

對於.NET 7,我們將控制檯應用和原生庫作為原生AOT的主要場景。應用程式開發人員和庫作者現在可以通過確保他們的應用程式是可調整的來利用原生AOT。由於剪裁是原生AOT編譯的必要條件,現在就為剪裁準備應用程式和庫將幫助它們為原生AOT做好準備。如果您是任何一個.NET庫的作者,遵循“剪裁庫”說明將幫助你為剪裁庫和原生AOT做好準備。

我們計劃在.NET 7中釋出的一個使用原生AOT編譯的應用是Crossgen工具。Crossgen是.NET SDK的一部分。CoreCLR AOT編譯器生成ReadyToRun可執行檔案。Crossgen是用c#編寫的,我們目前將其編譯後作為ReadyToRun應用釋出。在編譯速度和大小方面,我們已經看到了一些非常有前途的數字。Crossgen從原生AOT中獲益良多,因為它是一個短暫的程式,啟動開銷主導了整個執行時間:
image.png

展望未來,原生AOT的相容性將在.NET的下幾個版本中得到改善,但是在許多情況下總有理由選擇JIT。我們還將在dotnet SDK中為使用原生AOT釋出專案新增更多的支援。

可觀察性

.NET 7繼續對雲原生OpenTelemetry規範的支援。預覽版3增加了對規範升級#988#1708的支援,使取樣器的跟蹤狀態可變。

允許跟蹤取樣器修改活動跟蹤狀態

//  ActivityListener 取樣回撥
    listener.Sample = (ref ActivityCreationOptions<ActivityContext> activityOptions) =>
    {
        activityOptions = activityOptions with { TraceState = "rojo=00f067aa0ba902b7" };
        return ActivitySamplingResult.AllDataAndRecorded;
    };

System.Composition.Hosting

最新的託管可擴充套件性框架進行了輕微的更新,以與以前版本的API保持一致。新的API允許向System.Composition.Hosting容器新增單個物件例項。類似於遺留介面System.ComponentModel.Composition.Hosting中提供的功能以及ComposeExportedValue(compostioncontainer, T)(https://aka.ms/exportedvalue)

建議:將現有物件注入MEF2

namespace System.Composition.Hosting
{
      public class ContainerConfiguration{
 public ContainerConfiguration WithExport<TExport>(TExport exportedInstance);
 public ContainerConfiguration WithExport<TExport>(TExport exportedInstance,                             string contractName = null, IDictionary<string, object> metadata = null);
 public ContainerConfiguration WithExport(Type contractType, object exportedInstance);
 public ContainerConfiguration WithExport(Type contractType, object exportedInstance, string contractName = null, IDictionary<string, object> metadata = null);
    }
}

啟用Write-Xor-Execute後,啟動時間得到了改善

效能仍然是.NET 7的主要關注點。dotnet/runtime#65738 PR重新實現了預編碼和呼叫計數存根(分級編譯助手存根),以顯著減少執行時中可執行程式碼建立後修改的數量。這使得啟動時間提高了10-15%。

另外,即使沒有啟用Write-Xor-Execute,這種變化也會在一些微基準和一些ASPNet基準中帶來穩定狀態的效能提升(最高達8%)。

然而,在即將釋出的預覽版本中,也會有一些由該更改導致的迴歸(沒有啟用Write-Xor-Execute)。這是在Orchard和fortune對英特爾處理器的基準測試結果裡觀察到的。

迴圈優化

• 對於System.Collections.Tests.Perf_BitArray. BitArrayLeftShift(尺寸:512), 迴圈克隆將單次呼叫的持續時間提高了21%。

一般優化

GC regions預設啟用

在預覽版 3中,預設情況下啟用了region功能,該功能有助於提高高吞吐量應用程式的記憶體利用率。除了MacOS和原生AOT(將來會啟用),該功能現在已在所有平臺上啟用。更多細節可以訪問這個問題

由於region最初的分配方式,我們預計較小的應用程式的工作集會增加。如果您注意到任何功能或效能差異,請在runtime repo中建立一個問題。

密碼學:更好的生成X.500名稱

通過引入一個類,可以更清晰地解析X.500名稱,這一更改簡化了處理證書的工作。

讓構建x500distishedname更安全、更容易

一般來說,任何想要構建X.500名稱的人(比如用CertificateRequest類建立測試證書的人)都是通過字串操作來實現的,要麼是通過簡單的文字,要麼是通過字串格式化,例如:

request = new CertificateRequest($"CN={subjectName},OU=Test,O=""Fabrikam, Inc.""", ...);

這通常沒有問題,除非subjectName包含逗號、引號或任何對解析器有影響的內容。瞭解決這個問題,我們新增了x500 distishednamebuilder類。因為每個方法只對一個相對區別名(RDN)進行操作,所以解析過程中沒有歧義。另外,由於RDN識別符號得到了擴充套件,您不再需要猜測“CN”代表什麼
(“Common Name”)。

X500DistinguishedNameBuilder nameBuilder = new();
nameBuilder.AddCommonName(subjectName);
nameBuilder.AddOrganizationalUnitName("Test");
nameBuilder.AddOrganizationName("Fabrikam, Inc.");
​
request = new CertificateRequest(nameBuilder.Build(), ...);

針對.NET 7

針對目標.NET 7,你需要在你的專案檔案中使用.NET 7目標框架代號(TFM)。例如:

<TargetFramework>net7.0</TargetFramework>

請看完整的.NET 7 tfm集合,包括特定於操作的tfm。

  • net7.0
  • net7.0-android
  • net7.0-ios
  • net7.0-maccatalyst
  • net7.0-macos
  • net7.0-tvos
  • net7.0-windows

我們希望從.NET 6升級到.NET 7應該很簡單。歡迎告訴我們在使用.NET 7測試現有應用程式過程中發現的任何重大變化。

支援

.NET 7是一個當前版本,這意味著它將從釋出之日起18個月內獲得免費的支援和補丁。值得注意的是,所有版本的質量都是相同的。唯一的區別是支援的長度。有關.NET支援策略的更多資訊,請參閱.NET和.NET Core官方支援策略

重大的變化

通過閱讀.NET 7文件中的重大的變化,你可以找到.NET 7中最新的重大變化的列表。它按區域和版本列出了重大的變更,並提供了詳細解釋的連結。
要檢視有哪些重大的變化已經被提出來了,但是目前還是review階段,請follow.NET重大變化的github issue

路線圖

.NET的發行版包括產品、庫、執行時和工具,代表了微軟內部和外部多個團隊的協作。您可以通過閱讀產品路線圖來了解更多關於這些領域的資訊:

感謝您對.NET的所有支援和貢獻。請嘗試一下.NET 7預覽版3,告訴我們您的想法!
.NET 7預覽版3

相關文章