April 13th, 2022

Announcing .NET 7 Preview 3

Jon Douglas
Principal Program Manager

Today, we are glad to release .NET 7 Preview 3. The third preview of .NET 7 includes enhancements to observability, startup times, codegen, GC regions, native AOT compilation, and more. The bits are available for you to grab right now and start experimenting with new features like:

  • Native AOT
  • Default GC regions
  • ASP.NET Core startup time improvements

You can download .NET 7 Preview 3, for Windows, macOS, and Linux.

.NET 7 Preview 3 has been tested with Visual Studio 17.2 Preview 3. We recommend you use the preview channel builds if you want to try .NET 7 with Visual Studio family products. Visual Studio for Mac support for .NET 7 previews isn’t available yet but is coming soon. Now, let’s get into some of the latest updates in this release.

Faster, Lighter Apps with Native AOT

In the .NET 7 Preview 2 blog post, we announced that the Native AOT project has been moved out of experimental status and into mainline development in .NET 7 in the dotnet/runtime repo. We know that many of you have been eagerly awaiting updates from the team on what’s coming for Native AOT, and we have a couple of new updates for you for Preview 3.

If you want details about Native AOT, or to jump in and get started with it, the repo docs are the best place for that.

We also recognize that some of you might not be familiar with what Native AOT is, so we wanted to share a quick overview of it with you.

What is Native AOT?

Ahead-of-time (AOT) compilation refers to an umbrella of technologies which generate code at application build time, instead of run-time. AOT is not new to .NET. Today we ship ReadyToRun for client and server scenarios, and Mono AOT for mobile and WASM. Native AOT brings full native pre-compilation to .NET desktop client and server scenarios. Native AOT is not replacing these existing technologies, rather it’s offering a new set of capabilities that unlocks new form factors.

Existing AOT-compiled .NET assemblies contain platform-specific data structures and native code to frontload work typically done at runtime. Precompiling these artifacts saves time at startup (e.g. ReadyToRun), and enables access to no-JIT platforms (e.g. iOS). If precompiled artifacts are not present, .NET either falls back to JIT or interpretation (depending on the platform).

Native AOT is similar to .NET’s existing AOT technologies, but it produces only native artifacts. In fact, the Native AOT runtime does not know how to read the .NET assembly file formats – everything is platform-native. The executable file format parsing is fully handled by the underlying operating system.

The main advantage of Native AOT is in startup time, memory usage, accessing to restricted platforms (no JIT allowed), and smaller size on disk. Applications start running the moment the operating system pages in them into memory. The data structures are optimized for running AOT generated code, not for compiling new code at runtime. This is similar to how languages like Go, Swift, and Rust compile. Native AOT is best suited for environments where startup time matters the most. Targeting Native AOT has stricter requirements than general .NET Core/5+ applications and libraries. Native AOT forbids emitting new code at runtime (e.g. Reflection.Emit), and loading new .NET assemblies at runtime (eg. plug-in models).

Prepare your apps for Native AOT

For .NET 7 we are targeting console apps and native libraries as the primary scenario for Native AOT. Application developers and library authors can now take advantage of Native AOT by ensuring that their applications are trimmable. Since trimming is a requirement for Native AOT compilation, preparing your applications and libraries now for trimming will help them get ready for Native AOT as well. If you are an author of any .NET libraries, following the “Trimming libraries” instructions specifically will help you prepare your libraries for trimming and Native AOT.

One of the apps that we’re planning to ship in .NET 7 compiled with Native AOT is the crossgen tool. Crossgen is part of the .NET SDK. It’s the CoreCLR AOT compiler that produces ReadyToRun executables. Crossgen is written in C# and we currently ship it compiled with itself as a ReadyToRun app (it’s turtles all the way down!). We’re already seeing some very promising numbers in terms of compilation speed and size. Crossgen benefits heavily from Native AOT because it’s a short-lived process and the startup overhead dominates the overall execution time:

Scenario ReadyToRun NativeAOT
Compile CoreLib 4182 ms 3512 ms
Compile HelloWorld 185 ms 49 ms
Configuration Size
ReadyToRun 34.8 MB
NativeAOT 17.6 MB

Looking ahead, Native AOT compatibility will be improved over the next few versions of .NET, however there will always be reasons to prefer JIT for many scenarios. We will also add first-class support in the dotnet SDK for publishing projects with Native AOT.

Observability

.NET 7 continues to evolve support for the cloud native OpenTelemetry specification. Preview 3 adds support for specification updates #988 and #1708 that make the trace state mutable for samplers.

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

System.Composition.Hosting

The latest Managed Extensibility Framework gets a slight update to align with the previous version APIs. The new APIs allow adding a single object instance to the System.Composition.Hosting container. Similar to the functionality provided in the legacy interfaces System.ComponentModel.Composition.Hosting with the API ComposeExportedValue(CompositionContainer, T)

Proposal: Inject existing object into 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);
    }
}

Startup time improvements with Write-Xor-Execute enabled

Performance continues to be a major focus for .NET 7. The dotnet/runtime#65738 PR reimplemented the precode and call counting stubs (tiered compilation helper stubs) to significantly reduce number of post-creation modifications of executable code in the runtime. This resulted in 10-15% startup time improvements.

As a bonus, this change also resulted in steady state performance improvements (upto 8%) in some microbenchmarks and some ASPNet Benchmarks even without Write-Xor-Execute enabled.

However, there are few regressions resulting from that change too (without Write-Xor-Execute enabled) that will be addressed in the upcoming preview releases. These were observed in the Orchard and Fortunes benchmarks on Intel processors only.

CodeGen

Thanks in a large part to community contributors, Preview 3 features several optimizations and bug fixes to code generation and just-in time (JIT) compilation. Here’s an overview of the changes that are available today.

Community PRs

These pull requests were all initiated by community contributors.

From @clamp03
From @SkiFoD
From @sandreenko
From @SingleAccretion
From @trympet
From @Wraith2

Dynamic PGO

Arm64

Loop Optimizations

  • Loop Cloning improved the duration of single invocation by 21% for System.Collections.Tests.Perf_BitArray.BitArrayLeftShift(Size: 512): image

General Optimizations

GC Regions Enabled by default

With Preview 3, regions functionality which should help with memory utilization for high throughput applications has been enabled by default. The functionality is now enabled for all Platforms except MacOS and NativeAOT (which would be enabled in the future). More details are available in this issue: https://github.com/dotnet/runtime/issues/43844

We expect some working set increases for smaller applications due to how regions are initially allocated. If you notice any functional or performance differences please create an issue within the runtime repo.

Cryptography: Generating X.500 names more robustly

This change simplifies working with certificates by introducing a class that provides more clarity for parsing X.500 names.

Make it safer and easier to build an X500DistinguishedName

Classically, anyone wanting to build a X.500 name (such as for creating test certificates with the CertificateRequest class did so with string manipulation, either via a simple literal or with string formatting, e.g.

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

This is generally fine, except for when subjectName contains a comma, quote, or anything else that has an influence on the parser. To address that, we added the X500DistinguishedNameBuilder class. Because every method only operates on a single relative distinguished name (RDN), there’s no ambiguity in parsing. As a bonus, since the RDN identifiers are expanded, you no longer have to guess what “CN” stands for (“Common Name”).

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

request = new CertificateRequest(nameBuilder.Build(), ...);

Targeting .NET 7

To target .NET 7, you need to use a .NET 7 Target Framework Moniker (TFM) in your project file. For example:

<TargetFramework>net7.0</TargetFramework>

The full set of .NET 7 TFMs, including operating-specific ones follows.

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

We expect that upgrading from .NET 6 to .NET 7 should be straightforward. Please report any breaking changes that you discover in the process of testing existing apps with .NET 7.

Support

.NET 7 is a Current release, meaning it will receive free support and patches for 18 months from the release date. It’s important to note that the quality of all releases is the same. The only difference is the length of support. For more about .NET support policies, see the .NET and .NET Core official support policy.

Breaking changes

You can find the most recent list of breaking changes in .NET 7 by reading the Breaking changes in .NET 7 document. It lists breaking changes by area and release with links to detailed explanations.

To see what breaking changes are proposed but still under review, follow the Proposed .NET Breaking Changes GitHub issue.

Roadmaps

Releases of .NET include products, libraries, runtime, and tooling, and represent a collaboration across multiple teams inside and outside Microsoft. You can learn more about these areas by reading the product roadmaps:

Closing

We appreciate and thank you for your all your support and contributions to .NET. Please give .NET 7 Preview 3 a try and tell us what you think!

Author

Jon Douglas
Principal Program Manager

Jon Douglas is a Principal Program Manager for NuGet at Microsoft. In his spare time he is most likely spending time with his family, performing comedy improv, or playing video games.

25 comments

Discussion is closed. Login to edit/delete existing comments.

  • Daniel P

    Hi,

    What does Native AOT mean for Blazor?

    Thanks.

  • RoccoZero

    Please add COMPlus_legacyCorruptedStateExceptionsPolicy

  • LiFei

    Most people pay attention to the startup speed and size of desktop applications. Console programs are generally used by developers themselves, while dotnet is committed to optimizing the console and ignoring desktop applications. What’s the use of faster and smaller console startup

    • LiFei

      Any desktop application now, no matter WPF, WinForm, winui or Maui, is too bulky

  • B C · Edited

    We are having issues getting net7.0-android to be recognized. We are currently migrating from .net6 and are now getting this error with the android version in:

    error NU1012: Platform version is not present for one or more target frameworks, even though they have specified a platform: net7.0-android
    error NETSDK1139: The target platform identifier android was not recognized.

    Is android not supported in this release?

    EDIT: we are using TargetFrameworks instead of TargetFramework: net7.0-windows;net7.0-android
    We have to...

    Read more
      • B C

        Was this in response to my post? If so we don't use Maui. The only UI we use is for windows and it's WinForms only to present vulkan. We really want .net 7 for AOT, we had AOT running in the early .net 6 releases but at some point a newer .net 6 release broke it. I can run back and get the last version of .net 6 it last worked...

        Read more
    • Dawid Haładus

      create a class library, then two projects. One for running android version and one for winforms.

      • B C · Edited

        Appreciate the reply, but we did that but because of limitations on packaging, two of the libraries had to be merged into one csproj. We have a small library that uses almost no other references and it wont compile either and it doesnt use winforms at all.

        That said, We reverted the test machine back to .net6 and it would not compile any longer either. We removed the .net 7 sdk from add/remove programs...

        Read more
  • Dawid Haładus

    Will using AOT make the code not readily available through reverse engineering?
    Unfortunately, the current applications are easy to browse with e.g. dnSpy

    • Charles Roddie

      Yes, especially in reflection-free mode.

  • mrcat meow

    Would’ve loved to see native AOT for WPF. And I’m sure many people would love to see Windows 10 and Windows 11 styles for WPF too, which seems to be planned: https://github.com/dotnet/wpf/issues/5793

    • Max Mustermueller

      The problem is that the current WPF team has only taken over WPF and is also responsible for WinUI as far as I know which is their main job. So WPF has extremely low priority. You can easily see this on the issue response time and how long even simple PR's remain unreviewed for months. It is extremely unlikely that WPF gets any new features. Since it was open sourced it hasn't even got an...

      Read more
      • switchdesktopwithfade@hotmail.com

        You mean they were lying to us when they said they were hiring for WPF? They have the money and they notice. They know the business world is using WPF and they know that literally nobody cares about the whole garbage WinUI/WinRT stack. Do not accept their excuses, rather find out what nefarious project really has their attention like Pluton and TPM.

        What I gather is that TPTB don't like that you can create free-spirited Win32...

        Read more
      • Paulo Pinto

        Looking at WinUI lack of progress, and exponential set of github issues across all repos related to WinRT and WinUI tooling, they aren't also doing an exception job on that side either.

        And those .NET developers that have to deal with C++ stuff, and were robbed of C++/CX, also get to enjoy C++/WinRT with a development experience akin to the good old days of ATL development. Catching up with C++/CX tooling seems to be something, that...

        Read more
  • JinShil

    I suppose this is not the right place to post this, but I'm not sure where the right place is.

    What we really need from .NET right now is a way to deploy our .NET apps to a remote Linux computer (not WSL) and debug all with one click of the "Debug" button in Visual Studio. This works fine for Linux C++ apps in Visual Studio, but for .NET apps, it requires us to manually...

    Read more
  • Max Mustermueller

    My thoughts about NativeAOT are:

    So thanks for that but the way its (not) implemented it's not really useful, for me at least.

    Read more
    • Michal StrehovskyMicrosoft employee

      We plan to look into expanding the scenarios where NativeAOT is a good fit over time. It's a function of time and resources. It is already possible to use WinForms with NativeAOT, but it requires some polish and won't be advertised as a supported scenario because of that. I suggest following a .NET community member who helped to make a lot of progress on this over the years: Andrey Kurdyumov - https://twitter.com/Kurdiumov. Here's one of...

      Read more
      • Max Mustermueller

        What about WPF? It is quite known, also because of the several repo polls, that people are unsatisfied with the WPF development / repo owners so far. The recently updated roadmap doesn't show any NativeAOT support and every time we ask for that we get no answers.

        About the output size, like I said. There is a difference of 4.9mb between C++ and C# on a console project just printing "Hello World". I don't know exactly...

        Read more
      • Hughes, Danial

        Hi Max, I hope you're not expecting a response. I have posted MANY times on both here and the VS blog, and i NEVER get a response to WPF questions. We have a huge WPF codebase and the lack of support for the technology from Microsoft is appalling. Just look at the WPF Roadmap on github that this article links to and its clear there's nothing happening.
        We are currently evaluating non MS technology for...

        Read more
      • Jason Baginski

        Just a mention because I have one sitting in front of me. A small console app I wrote to do some minor sort/consolidation on some config files on our mail server is 16,384 bytes with .NET Framework 4.8. 163,776 in .NET 6.0 and 165,317 in NET 6.0 with ReadyToRun. Sure, it’s quite a bit larger, but it’s 147kb, not 4.9mb.

      • Charles Roddie

        The state of dotnet AOT platform support on MAUI is yes for iOS, Mac catalyst, android (via monovm aot), and no for Windows (regression from Xamarin since UWP has AOT but WinUI hasn't).

        The regression on Windows is more a matter of politics than time and resources. The work is being done by Andrey but the team is stalling (https://github.com/microsoft/CsWinRT/issues/989#issuecomment-921911755, https://github.com/microsoft/CsWinRT/issues/999). They are treating reflection support as a reason to avoid generics (!), putting a tiny...

        Read more