.NET 10 is now available: the most productive, modern, secure, intelligent, and performant release of .NET yet.
Announcing .NET 5.0
We’re excited to release .NET 5.0 today and for you to start using it. It’s a major release — includingC# 9 andF# 5 — with a broad set of new features and compelling improvements. It’s already in active use by teams at Microsoft and other companies, in production and for performance testing. Those teams are showing us great results that demonstrate performance gains and/or opportunities to reduce hosting costs for their web applications. We’ve been runningour own website on 5.0 since Preview 1. From what we’ve seen and heard so far, .NET 5.0 delivers significant value without much effort to upgrade. It’s a great choice for your next app, and a straightforward upgrade from earlier .NET Core versions. We hope you enjoy using it, on your desktop, laptop, and cloud instances.
ASP.NET Core,EF Core,C# 9, andF# 5 are also being released today..NET Conf 2020 — ourfree and virtual conference — is being held today so you can learn about all of the new releases.
You candownload .NET 5.0, for Windows, macOS, and Linux, for x86, x64, Arm32, Arm64.
- Installers and binaries
- Container images
- Linux packages
- Release notes
- Known issues
- GitHub issue tracker
- .NET 5.0 Contributors
For Visual Studio users, you needVisual Studio 16.8 or later to use .NET 5.0 on Windows and the latest version ofVisual Studio for Mac) on macOS. TheC# extension forVisual Studio Code already supports .NET 5.0 and C# 9.
.NET 5.0 is the first release in our .NET unification journey. We built .NET 5.0 to enable a much larger group of developers to migrate their .NET Framework code and apps to .NET 5.0. We’ve also done much of the early work in 5.0 so that Xamarin developers can use the unified .NET platform when we release .NET 6.0. There is more on .NET unification, later in the post.
Now is a good time to call out the incredible collaboration with everyone contributing to the .NET project. This release marks the fifth major .NET version as an open source project. There is now a large mix of individuals and small and large companies (including the.NET Foundation corporate sponsors) working together as a large community on various aspects of .NET in thedotnet org on GitHub. The improvements in .NET 5.0 are the result of many people, their effort, smart ideas, and their care and love for the platform, all above and beyond Microsoft’s stewardship of the project. From the core team working on .NET every day, we extend avery large “thank you” to everyone that contributed to .NET 5.0 (and previous releases)!
Weintroduced .NET 5.0 way back in May 2019, and even set the November 2020 release date at that time. From that post: “we will ship .NET Core 3.0 this September, .NET 5 in November 2020, and then we intend to ship a major version of .NET once a year, every November”. You’d think that “November 2020” was a cheque that could not be cashed given all the challenges this year, however, .NET 5.0 has been released on time. Thanks to everyone on the team that made that happen! I know it has not been easy. Looking forward, you should expect .NET 6.0 in November 2021. We intend to release new .NET versions every November.
The rest of the blog is dedicated to highlighting and detailing most of the improvements in .NET 5.0. There is also an update on our .NET unification vision.
.NET 5.0 Highlights
There are manyimportant improvements in .NET 5.0:
- .NET 5.0 is already battle-tested by being hosted for months atdot.net andBing.com (version).
- Performance is greatly improved across many components and is described in detail atPerformance Improvements in .NET 5.0,Arm64 Performance in .NET 5.0, andgRPC.
- C# 9 and F# 5 offer new language improvements such as top-level programs and records for C# 9, while F# 5 offers interactive programming and a performance boost for functional programming on .NET.
- .NET libraries have enhanced performancefor Json serialization,regular expressions, and HTTP (HTTP 1.1,HTTP/2). They are also are now completely annotated for nullability.
- P95 latency has dropped due to refinements in theGC,tiered compilation, andother areas.
- Application deployment options are better, with ClickOnce client app publishing,single-file apps,reduced container image size, and the addition of Server Core container images.
- Platform scope expanded withWindows Arm64 andWebAssembly.
I’ve written many samples for the .NET 5.0 preview posts. You might want to take a look at.NET 5.0 Examples to learn more about new C# 9 and libraries features.
Platform and Microsoft Support
.NET 5.0 has a nearly identicalplatform support matrix as.NET Core 3.1, for Windows, macOS, and Linux. If you are using .NET Core 3.1 on a supported operating system, you should be able to adopt .NET 5.0 on that same operating system version for the most part. The most significant addition for .NET 5.0 is Windows Arm64.
.NET 5.0 is acurrent release. That means that it will be supported for three months after .NET 6.0 is released. As a result, we expect to support .NET 5.0 through the middle of February 2022. .NET 6.0 will be an LTS release and will be supported for three years, just like .NET Core 3.1.
Unified platform vision
Last year, we shared avision of a unified .NET stack and ecosystem. The value to you is that you will be able to use a single set of APIs, languages, and tools to target a broad set of application types, including mobile, cloud, desktop, and IoT. You might realize that you can already target a broad set of platforms with .NET today, however, the tools and APIs are not always the same across Web and Mobile, for example, or released at the same time.
As part of .NET 5.0 and 6.0, we are unifying .NET into a single product experience, while enabling you to pick just the parts of the .NET platform that you want to use. If you want to target Mobile and not WebAssembly, you don’t need to download the WebAssembly tools, and vice versa. Same with ASP.NET Core and WPF. You’ll also have a much easier way to acquire all the .NET tools and build and runtime packs that you need from the command line. We’re enabling a package manager experience (including using existing package managers) for .NET platform components. That will be great for many scenarios. Quick construction of a development environment and CI/CD will probably be the biggest beneficiaries.
We had intended to deliver the entirety of the unification vision with .NET 5.0, but in the wake of the global pandemic, we had to adapt to the changing needs of our customers. We’ve been working with teams from companies from around the world that have needed help to speed up their adoption of cloud technologies. They, too, have had adapt to the changing needs of their customers. As a result, we are delivering the vision across two releases.
The first step towards this vision wasconsolidating .NET repos, including a large subset of Mono. Having one repo for the runtime and libraries for .NET is a precondition to delivering the same product everywhere. It also helps with making broad changes that affect runtime and libraries, where there were previously repo boundaries. Some people were worried that a large repo would be harder to manage. That hasn’t proven to be the case.
In the .NET 5.0 release, Blazor is best example of taking advantage of repo consolidation and .NET unification. The runtime and libraries forBlazor WebAssembly are now built from the consolidateddotnet/runtime repo. That means Blazor WebAssembly and Blazor on the server use the exact same code forList<T>, for example. That wasn’t the case for Blazor prior to .NET 5.0. The approach we took for Blazor WebAssembly is very similar to what we’ll do with Xamarin in .NET 6.0.
The .NET Framework remains a supported Microsoft product and will continue to be supported with each new version of Windows. We announced last year that we hadstopped adding new features to .NET Framework andfinished adding .NET Framework APIs to .NET Core. That means that now is a great time to consider moving your .NET Framework apps to .NET Core. For .NET Framework client developers, Windows Forms and WPF are supported with .NET 5.0. We’ve heard from many developers that porting from .NET Framework is straightforward. For .NET Framework server developers, you need to adopt ASP.NET Core to use .NET 5.0. For Web Forms developers, we believe thatBlazor provides a similar developer experience with an efficient and much more modern implementation. WCF server and Workflow users can look tocommunity projects that are supporting those frameworks. Theporting from .NET Framework to .NET Core doc is a good place to start. That all said, keeping your app on .NET Framework is a fine approach if you are happy with your experience.
The Windows team is working onProject Reunion as the next step forward for UWP and related technologies. We’ve been collaborating with the Reunion team to ensure that .NET 5.0 and later versions will work well with WinUI and WebView2. The Project Reunion repo is the best place to stay up to date with progress.
Let’s switch to looking at what’s new in the 5.0 release.
Languages
C# 9 andF# 5 are part of the .NET 5.0 release and included in the .NET 5.0 SDK. Visual Basic is also included in the 5.0 SDK. It does not include language changes, but has improvements to support the Visual Basic Application Framework on .NET Core.
C# Source Generators are an important new C# compiler feature. They are not technically part of C# 9 since it doesn’t have any language syntax. SeeNew C# Source Generator Samples to help you get started using this new feature. We expect to make more use ofsource generators within the .NET product in .NET 6.0 and beyond.
As a way to try out the new release ourselves, a few of us decided to update thedotnet/iot repo to use new C# 9 syntax and target .NET 5.0. The changes resulted in removing >2k lines of code, just by adopting new syntax. It uses top-level programs, records, patterns, and switch expressions. It has also been updated to take advantage of the complete set of nullable annotations in .NET libraries. We also updated the.NET IoT docs. We’ll take a look at few examples from that repo to explore C# 9.
Top-level programs
Theled-blink program is a nice compact top-level program example.
using System;using System.Device.Gpio;using System.Threading;var pin = 18;var lightTime = 1000;var dimTime = 200;Console.WriteLine($"Let's blink an LED!");using GpioController controller = new ();controller.OpenPin(pin, PinMode.Output);Console.WriteLine($"GPIO pin enabled for use: {pin}");// turn LED on and offwhile (true){ Console.WriteLine($"Light for {lightTime}ms"); controller.Write(pin, PinValue.High); Thread.Sleep(lightTime); Console.WriteLine($"Dim for {dimTime}ms"); controller.Write(pin, PinValue.Low); Thread.Sleep(dimTime);}You can also see the use of target-typednew, with the assignment to thecontroller variable. TheGpioController type is only defined on the left-hand side of the assignment. The type is inferred on the right-hand side. This new syntax is an alternative tovar, which has the type only showing on the right-hand side of the assignment and is inferred on the left-hand side with thevar keyword.
Top-level programs can also grow in complexity, by defining methods and taking advantage of types defined in the same or other files. TheCharacterLcd sample demonstrates some of those capabilities.
Logical and property patterns
C# 9 includes support for new patterns. You can see an example of a logical pattern in thefollowing code from theCCS811 Gas sensor.
var threshChoice = Console.ReadKey();Console.WriteLine();if (threshChoice.KeyChar is 'Y' or 'y'){ TestThresholdAndInterrupt(ccs811);}Another new pattern is property patterns. You can see several properties checks in myMycroft information access 6.0 sample. Thefollowing code is taken from thePN532 RFID and NFC reader sample.
if (pollingType is null or { Length: >15 }){ return null;}This code tests ifpollingType (which is typed asbyte[]?) is null or contains >15 bytes.
I want to show you two more patterns. The first is alogical pattern inMcp25xxx CAN bus.
public static byte GetRxBufferNumber(Address address) => address switch{ >= Address.RxB0D0 and <= Address.RxB0D7 => 0, >= Address.RxB1D0 and <= Address.RxB1D7 => 1, _ => throw new ArgumentException(nameof(address), $"Invalid address value {address}."),};The second is alogical pattern inPiezo Buzzer Controller.
if (element is not NoteElement noteElement){ // In case it's a pause element we have only just wait desired time. Thread.Sleep(durationInMilliseconds);}else{ // In case it's a note element we play it. var frequency = GetFrequency(noteElement.Note, noteElement.Octave); _buzzer.PlayTone(frequency, (int)(durationInMilliseconds * 0.7)); Thread.Sleep((int)(durationInMilliseconds * 0.3));}Records
C# 9 includes a new type of class called a record. It has a number of benefits compared to regular classes, half of which relate to more terse syntax. Thefollowing record is taken from theBh1745 RGB Sensor binding.
public record ChannelCompensationMultipliers(double Red, double Green, double Blue, double Clear);It is then useda little later in the same file, with familiar syntax:
ChannelCompensationMultipliers = new (2.2, 1.0, 1.8, 10.0);Nullability annotation improvements
The .NET libraries are now completely annotated fornullability. That means if youenable nullability, you’ll get more type information from the platform to direct your use of the feature. At present, the.NET docs have not been fully annotated. For example,String.IsNullOrEmpty(string) should be annotated to take astring?, whileString.Split(Char[]) has an annotation ofchar[]?. We hope that will get fixed soon. Complete information is available atsource.dot.net and via F12 metadata lookups in Visual Studio.
TheSystem.Device.Gpio andIot.Device.Bindings packages (version 1.1.0 for both) have also been annotated as part of this release, using the updated .NET 5.0 annotations. Those libraries are both multi-targeted, however, we use the 5.0 view to produce annotations for all targets.
Note: Existing .NET Core 3.1 code might generate new diagnostics (if you have nullability enabled) when you retarget it to .NET 5.0, since there are new annotations.
We’ve also added new annotation types. It’s common for large classes to instantiate object members in helper methods called from a constructor. The C# compiler can’t follow the flow of calls to the object assignment. It will think that the member is null when exiting the constructor and will warn withCS8618. TheMemberNotNull attribute resolves this problem. You apply the attribute to the helper method. The compiler will then see that you set this value and realize that the method is called from a constructor.MemberNotNullWhen is similar.
You can see an example ofMemberNotNull in theBMxx80 temperature sensors with thefollowing code.
[MemberNotNull(nameof(_calibrationData))]private void ReadCalibrationData(){ switch (this) { case Bme280 _: _calibrationData = new Bme280CalibrationData(); _controlRegister = (byte)Bmx280Register.CTRL_MEAS; break; case Bmp280 _: _calibrationData = new Bmp280CalibrationData(); _controlRegister = (byte)Bmx280Register.CTRL_MEAS; break; case Bme680 _: _calibrationData = new Bme680CalibrationData(); _controlRegister = (byte)Bme680Register.CTRL_MEAS; break; default: throw new Exception("Bmxx80 device not correctly configured. Could not find calibraton data."); } _calibrationData.ReadFromDevice(this);}Theactual code uses conditional compilation. That’s because the project is multi-targeted, and this attribute is only supported with .NET 5.0+ . The use of the attribute enables skipping runtime checks (in the constructor) that would otherwise be needed to satisfy nullability requirements, asis the case for earlier .NET versions.
Tools
We’ve improved the Windows Forms designer, changed the way that target frameworks work for .NET 5.0 and beyond, changed the way that WinRT is supported, and made other improvements.
Windows Forms designer
The Windows Forms designer (for .NET Core 3.1 and .NET 5.0) has been updated in Visual Studio 16.8, and now supports all Windows Forms controls. It also supports theTelerik UI for WinForms controls. The designer includes all the designer functionality you would expect, including: drag-and-drop, selection, move and resize, cut/copy/paste/delete of controls, integration with the Properties Window, events generation and more. Data binding and support for a broader set of third party controls is coming soon.

Learn more in theWindows Forms Designer for .NET Core Released post.
.NET 5.0 Target Framework
We have changed the approach we use fortarget frameworks with .NET 5.0. The following project file demonstrate the new .NET 5.0 target framework.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> </PropertyGroup></Project>The newnet5.0 form is more compact and intuitive than thenetcoreapp3.1 style we’ve used until this point. In addition, we are extending the target framework to describe operating system dependencies. This change is motivated by our vision to enable targeting iOS and Android with Xamarin in .NET 6.0.
Windows desktop APIs (including Windows Forms, WPF, and WinRT) will only be available when targetingnet5.0-windows. You can specify an operating system version, likenet5.0-windows7 ornet5.0-windows10.0.17763.0 ( forWindows October 2018 Update). You need to target a Windows 10 version if you want to useWinRT APIs.
Cross-platform scenarios can be a bit more challenging, when using the newnet5.0-windows TFM.System.Device.Gpio demonstratesa pattern for managing the Windows target-framework if you want to avoid building for Windows or avoid pulling Windows runtime packages on Linux, for example.
Summary of changes:
net5.0is the new Target Framework Moniker (TFM) for .NET 5.0.net5.0combines and replacesnetcoreappandnetstandardTFMs.net5.0supports.NET Framework compatibility modenet5.0-windowswill be used to expose Windows-specific functionality, including Windows Forms, WPF and WinRT APIs.- .NET 6.0 will use the same approach, with
net6.0, and will addnet6.0-iosandnet6.0-android. - The OS-specific TFMs can includeOS version numbers, like
net6.0-ios14. - Portable APIs, like ASP.NET Core will be usable with
net5.0. The same will be true of Xamarin forms withnet6.0.
The templates in Visual Studio 16.8 still target .NET Core 3.1, for console, WPF and Windows Forms apps. The ASP.NET templates have been updated to support .NET 5.0. We will update the templates in Visual Studio 16.9 for the remaining templates.
WinRT Interop (Breaking Change)
On the topic of targeting Windows APIs, we have moved to anew model for supporting WinRT APIs as part of .NET 5.0. This includes calling APIs (in either direction; CLR <==> WinRT), marshaling of data between the two type systems, and unification of types that are intended to be treated the same across the type system orABI boundary (i.e. “projected types”;IEnumerable<T> andIIterable<T> are examples).
Theexisting WinRT interop system has been removed from the .NET runtime as part of .NET 5.0. This is a breaking change. That means that apps and libraries using WinRT with .NET Core 3.x will need to be rebuilt and will not run on .NET 5.0 as-is. Libraries that use WinRT APIs will need to multi-target to manage this difference between .NET Core 3.1 and .NET 5.0.
Going forward, we will rely on the newCsWinRT tool provided by the WinRT team in Windows. It generates C#-based WinRT interop assemblies, which can be delivered via NuGet. That’s exactly what the Windows team is doing, for the WinRT APIs in Windows. The tool can be used by anyone that wants to use WinRT (on Windows) as an interop system, to expose native APIs to .NET or .NET APIs to native code.
TheCsWinRT tool is logically similar to tlbimp and tlbexp, although much better. The tlb tools relied on a lot of COM interop plumbing in the .NET runtime. The CsWinRT tool only relies on public .NET APIs. That said, thefunction pointers feature in C# 9 — and partially implemented in the .NET 5.0 runtime — was in part inspired by the needs of the CsWinRT tool.
There are several benefits to this new WinRT interop model:
- It can be developed and improved separate from the .NET runtime.
- It is symmetrical with the tool-based interop systems provided for other OSes, like iOS and Android.
- The tool can take advantage of other .NET features (AOT, C# features, IL linking), which was not an option for the previous system.
- Simplifies the.NET runtime codebase.
You don’t need to add NuGet references to use WinRT APIs. Targeting a Windows 10 TFM — just discussed in the .NET 5.0 TFM section earlier — is enough. If you target .NET Core 3.1 or earlier, you need to reference WinRT packages. You can see this pattern in theSystem.Device.Gpio project.
Native exports
We’ve had requests to enable exports for native binaries that calls into .NET code for a long time. The building block for the scenario ishosting API support forUnmanagedCallersOnlyAttribute.
This feature is a building-block for creating higher level experiences.Aaron Robinson, on our team, has been working on a.NET Native Exports project that provides a more complete experience for publishing .NET components as native libraries. We’re looking for feedback on this capability to help decide if the approach should be included in the product.
The .NET Native exports project enables you to:
- Expose custom native exports.
- Doesn’t require a higher-level interop technology like COM.
- Works cross-platform.
There are existing projects that enable similar scenarios, such as:
Over the years, we’ve seen a variety of hosting models for .NET in native applications.@rseanhall proposed and implementeda novel new model for doing that, which takes advantage of all the built-in application functionality offered by the .NET application hosting layer (specifically loading dependencies), while enabling a custom entrypoint to be called from native code. That’s perfect for a lot of scenarios, and that one can imagine becoming popular with developers that host .NET components from native applications. That didn’t exist before. Thanks for the contribution,@rseanhall.
Two primary PRs:
Event pipe
Event pipe is a new subsystem and API that we added in.NET Core 2.2 to make it possible to performperformance and other diagnostic investigations on any operating system. In .NET 5.0, the event pipe has been extended to enable profilers to write event pipe events. This scenario is critical for instrumenting profilers that previously relied on ETW (on Windows) to monitor application behavior and performance.
Assembly load information is now available via event pipe. This improvement is the start of making similar diagnostics functionality available as is part of .NET Framework, such as theFusion Log Viewer. You can now usedotnet-trace to collect this information, using the following command:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4:4 -- ./MyApp –my-arg 1
The workflow is described in thedotnet-trace docs. You can see assembly loading information for a simple test app.

Microsoft.Extensions.Logging
We’ve made improvements to the console log provider in theMicrosoft.Extensions.Logging library. You can now implement acustomConsoleFormatter to exercise complete control over formatting and colorization of the console output. The formatter APIs allow for rich formatting by implementing a subset of theVT-100 (supported by most modern terminals) escape sequences. The console logger can parse out escape sequences on unsupported terminals allowing you to author a single formatter for all terminals.
In addition to support for custom formatters, we’ve also added a built-in JSON formatter that emits structured JSON logs to the console.
Dump debugging
Debugging managed code requires knowledge of managed objects and constructs. The Data Access Component (DAC) is a subset of the runtime execution engine that has knowledge of these constructs and can access these managed objects without a runtime. .NET Core process dumps collected on Linux can now be analyzed on Windows using WinDBG ordotnet dump analyze.
We’ve also added support for capturing ELF dumps from .NET processes running on macOS. Since ELF is not the native executable (native debuggers likelldb will not work with these dumps) file format on macOS, we have made this an opt-in feature. To enable support for dump collection on macOS, set the environment variableCOMPlus_DbgEnableElfDumpOnMacOS=1. The resulting dumps can be analyzed usingdotnet dump analyze.
Printing environment information
As .NET has extended support for new operating systems and chip architectures, people sometimes want a way to print environment information. We created a simple .NET tool that does this, calleddotnet-runtimeinfo.
You can install and run the tool with the following commands.
dotnet tool install -g dotnet-runtimeinfodotnet-runtimeinfoThe tool produces output in the following form for your environment.
**.NET informationVersion: 5.0.0FrameworkDescription: .NET 5.0.0Libraries version: 5.0.0Libraries hash: cf258a14b70ad9069470a108f13765e0e5988f51**Environment informationOSDescription: Linux 5.8.6-1-MANJARO-ARM #1 SMP Thu Sep 3 22:01:08 CEST 2020OSVersion: Unix 5.8.6.1OSArchitecture: Arm64ProcessorCount: 6**CGroup info**cfs_quota_us: -1memory.limit_in_bytes: 9223372036854771712memory.usage_in_bytes: 2740666368Runtime and Libraries
There were many improvements across the runtime and libraries.
Code quality improvements in RyuJIT
There were a lot of improvements to the JIT this release, many of which I shared in previous .NET 5.0 preview posts. In this post, I’m elevating the changes that came from the community.
- Use xmm for stack prolog – dotnet/runtime #32538 — Change to x86/x64 prolog zeroing code. Improvements:Json;TechEmpower. Credit:Ben Adams.
- Vectorise BitArray for Arm64 – dotnet/runtime #33749 — TheBitArray class was updated to include ahardware-accelerated implementation for Arm64 usingArm64 intrinisics. Theperformance improvements for BitArray are very significant. Credit to@Gnbrkm41.
- Dynamic generic dictionary expansion feature dotnet/runtime #32270 – Some (maybe most?) uses of generics now have better performance (initial performance findings), based on improving the implementation of low-level (native code) dictionaries used by the runtime to store information about generic types and methods. SeePerf: Collection Count() is Slower in Core than the CLR for more information. Credit to@RealDotNetDave for the bug report.
- Implement Vector.Ceiling / Vector.Floor dotnet/runtime #31993 – Implement Vector.Ceiling / Vector.Floor using x64 and Arm64 intrinsics, perAPI proposal. Credit to@Gnbrkm41.
- New, much faster, portable implementation of tailcall helpers. Credit:Jakob Botsch Nielsen (.NET team intern).Reaction from @dsymetweets.
- Add VectorTableList and TableVectorExtension intrinsics — Credit:@TamarChristinaArm (ARM Holdings)
- Improved Intel architecture performance using new hardware intrinsics BSF/BSR — Credit@saucecontrol
- Implement Vector{Size}.AllBitsSet — Credit@Gnbrkm41
- Enable eliding some bounds checks — Credit@nathan-moore
Garbage Collector
The following improvements were made in the GC.
- Card mark stealing – dotnet/coreclr #25986 — Server GC (on different threads) can now work-steal while marking gen0/1 objects held live by older generation objects. This means that ephemeral GC pauses are shorter for scenarios where some GC threads took much longer to mark than others.
- Introducing Pinned Object Heap – dotnet/runtime #32283 — Adds the Pinned Object Heap (POH). This new heap (a peer to the Large Object Heap (LOH)) will allow the GC to manage pinned objects separately, and as a result avoid the negative effects of pinned objects on the generational heaps.
- Allow allocating large object from free list while background sweeping SOH — Enabled LOH allocations using the free list while BGC is sweeping SOH. Previously this was only using end of segment space on LOH. This allowed for better heap usage.
- Background GC suspension fixes – dotnet/coreclr #27729 — Suspension fixes to reduce time for both BGC and user threads to be suspended. This reduces the total time it takes to suspend managed threads before a GC can happen.dotnet/coreclr #27578 also contributes to the same outcome.
- Fix named cgroup handling in docker — Added support to read limits from named cgroups. Previously we only read from the global one.
- Optimize vectorized sorting – dotnet/runtime #37159 — vectorized mark list sorting in GC which reduces the ephemeral GC pause time (alsodotnet/runtime #40613).
- Generational aware analysis – dotnet/runtime #40322 — generational aware analysis that allows you to determine what old generation objects hold on to younger generation objects thus making them survive and contribute to ephemeral GC pause time.
- Optimize decommitting GC heap memory pages – dotnet/runtime #35896 — optimized decommit, much better decommit logic and for Server GC took decommit completely out of the “stop the world” phase which reduced blocking GC pause time.
The GC now exposes detailed information of the most recent collection, via theGC.GetGCMemoryInfo method. TheGCMemoryInfo struct provides information about machine memory, heap memory and the most recent collection, or most recent collection of the kind of GC you specify – ephemeral, full blocking or background GC.
The most likely use cases for using this new API are for logging/monitoring or to indicate to a loader balancer that a machine should be taken out of rotation to request a full GC. It could also be used to avoid container hard-limits by reducing the size of caches.
Another, small but impactful change, was made todefer the expensivereset memory operation to low-memory situations. We expect these changes in policy to lower the GC latency (and GC CPU usage in general).
Windows Arm64
.NET apps can now run natively on Windows Arm64. This follows the support we added for Linux Arm64 (support for glibc and musl) with .NET Core 3.0. With .NET 5.0, you can develop and run apps on Windows Arm64 devices, such asSurface Pro X. You can already run .NET Core and .NET Framework apps on Windows Arm64, but via x86 emulation. It’s workable, but native Arm64 execution has much better performance.
MSI installers for Arm64 were one of the final changes this release. You can see the .NET 5.0 SDK installer in the following image.

The .NET 5.0 SDK does not currently contain the Windows Desktop components — Windows Forms and WPF — on Windows Arm64. This change was initially shared in the.NET 5.0 Preview 8 post. We are hoping to add the Windows desktop pack for Windows Arm64 in a 5.0 servicing update. We don’t currently have a date to share. Until then, the SDK, console and ASP.NET Core applications are supported on Windows Arm64, but not Windows Desktop components.
Arm64 Performance
We’ve been investing significantly in improving Arm64 performance, for over a year. We’re committed to making Arm64 a high-performance platform with .NET. These improvements apply equally to Windows and Linux. Platform portability and consistency have always been compelling characteristics of .NET. This includes offering great performance wherever you use .NET. With .NET Core 3.x, Arm64 has functionality parity with x64 but is missing some key performance features and investments. We’ve resolved that in .NET 5.0, as described inArm64 Performance in .NET 5.0.
The improvements:
- Tune JIT optimizations for Arm64 (example)
- Enable and take advantage of Arm64 hardware intrinsics (example).
- Adjust performance-critical algorithms in libraries for Arm64 (example).
SeeImproving Arm64 Performance in .NET 5.0 for more details.
Hardware intrinsics are alow-level performance feature we added in .NET Core 3.0. At the time, we added support for x86-64 instructions and chips. As part of .NET 5.0, we are extending the feature to support Arm64. Just creating the intrinsics doesn’t help performance. They need to be used in performance-critical code. We’ve taken advantage ofArm64 intrinsics extensively in .NET libraries in .NET 5.0. You can also do this in your own code, although you need to be familiar with CPU instructions to do so.
I’ll explain how hardware intrinsics work with an analogy. For the most part, developers rely on types and APIs built into .NET, likestring.Split orHttpClient. Those APIs often take advantage of native operating system APIs, via theP/Invoke feature. P/Invoke enables high-performance native interop and is used extensively in the .NET libraries for that purpose. You can use this same feature yourself to call native APIs. Hardware intrinsics are similar, except instead of calling operating system APIs, they enable you to directly use CPU instructions in your code. It’s roughly equivalent to a .NET version ofC++ intrinsics. Hardware intrinsics are best thought of as a CPU hardware-acceleration feature. They provide very tangible benefits and are now a key part of the performance substrate of the .NET libraries, and responsible for many of the benefits you can read about in the.NET 5.0 performance post. In terms of comparison to C++, when .NET intrinsics are AOT-compiled into Ready-To-Run files, the intrinsics have no runtime performance penalty.
Note: The Visual C++ compiler has an analogousintrinsics feature. You can directly compare C++ to .NET hardware intrinsics, as you can see if you search for_mm_i32gather_epi32 atSystem.Runtime.Intrinsics.X86.Avx2,x64 (amd64) intrinsics list, andIntel Intrinsics guide. You will see a lot of similarity.
We’re making our first big investments in Arm64 performance in 5.0, and we’ll continue this effort in subsequent releases. We work directly with engineers fromArm Holdings to prioritize product improvements and to design algorithms that best take advantage of theArmv8 ISA. Some of these improvements will accrue value to Arm32, however, we are not applying unique effort to Arm32. If you use a Raspberry Pi, you’ll enjoy these improvements if you install the new Arm64 version of Raspberry Pi OS.
We expect that Apple will announce new Apple Silicon-based Mac computers any day now. We already have early builds of.NET 6.0 for Apple Silicon and have been working with Apple engineers to help optimize .NET for that platform. We’ve also had someearly community engagement on Apple Silicon (Credit@snickler).
P95+ Latency
We see an increasing number of large internet-facing sites and services being hosted on .NET. While there is a lot of legitimate focus on therequests per second (RPS) metric, we find that no big site owners ask us about that or require millions of RPS. We hear a lot about latency, however, specifically about improvingP95 or P99 latency. Often, the number of machines or cores that are provisioned for (and biggest cost driver of) a site are chosen based on achieving a specific P95 metric, as opposed to say P50. We think of latency as being the true “money metric”.
Our friends at Stack Overflow do a great job of sharing data on their service. One of their engineers, Nick Craver, recently sharedimprovements they saw to latency, as aresult of moving to .NET Core:
The median page render time for questions dropped from about 21 ms (we were up a bit lately due to GC) to ~15ms.
The 95th percentile dropped from ~40ms to ~30ms (same measurement). 99th dropped from ~60ms to ~45ms.
Not too shabby, given we haven’t optimized anything at all yet.pic.twitter.com/MMHjI9wkuL
— Nick Craver (@Nick_Craver)March 31, 2020
Pinned objects have been a long-term challenge for GC performance, specifically because they accelerate (or cause) memory fragmentation. We’ve added anew GC heap for pinned objects. Thepinned object heap is based on the assumption that there are very few pinned objects in a process but that their presence causes disproportionate performance challenges. It makes sense to move pinned objects — particularly those created by .NET libraries as an implementation detail — to a unique area, leaving the generational GC heaps with few or no pinned objects, and with substantially higher performance as a result.
More recently, we’ve been attacking long-standing challenges in the GC.dotnet/runtime #2795 applies a new approach to GC statics scanning that avoids lock contention when it is determining liveness of GC heap objects.dotnet/runtime #25986 uses a new algorithm for balancing GC work across cores during the mark phase of garbage collection, which should increase the throughput of garbage collection with large heaps, which in turn reduces latency.
Improving tiered compilation performance
We’ve been working on improvingtiered compilation for multiple releases. We continue to see it as a critical performance feature, for both startup and steady-state performance. We’ve made two big improvements to tiered compilation this release.
The primary mechanism underlying tiered compilation is call counting. Once a method is called n times, the runtime asks the JIT to recompile the method at higher quality. From our earliest performance analyses, we knew that the call-counting mechanism was too slow, but didn’t see a straightforward way to resolve that. As part of .NET 5.0, we’veimproved the call counting mechanism used by tiered JIT compilation to smooth out performance during startup. In past releases, we’ve seen reports of unpredictable performance during the first 10-15s of process lifetime (mostly for web servers). That should now be resolved.
Another performance challenge we found was using tiered compilation for methods with loops. The fundamental problem is that you can have a cold method (only called once or a few times; $lt; n) with a loop that iterates many times. We call this pathological scenario “cold method; hot loop”. It is easy to imagine this happening with theMain method of an application. As a result, we disabled tiered compilation for methods with loops by default. Instead, we enabled applications to opt into using tiered compilation with loops. PowerShell is an application that chose to do this, after seeing high single-digit performance improvements in some scenarios.
To address methods with loops better, we implementedon-stack replacement (OSR). This is similar to a feature that the Java Virtual Machines has, of the same name.OSR enables code executed by a currently running method to be re-compiled in the middle of method execution, while those methods are active “on-stack”. This feature is currently experimental and opt-in, and on x64 only.
To use OSR, multiple features must be enabled. ThePowerShell project file is a good starting point. You will notice that tiered compilation and all quick-jit features are enabled. In addition, you need to set theCOMPlus_TC_OnStackReplacement environment variable to1.
Alternatively, you can set the following two environment variables, assuming all other settings have their default values:
COMPlus_TC_QuickJitForLoops=1COMPlus_TC_OnStackReplacement=1
We do not intend to enable OSR by default in .NET 5.0 and have not yet decided if we will support it in production.
Support for ICU on Windows
We use theICU library for Unicode and globalization support, previously only on Linux and macOS. We are now usingthis same library on Windows 10.This change makes the behavior of globalization APIs such as culture-specific string comparison consistent between Windows 10, macOS, and Linux. We also use ICU with Blazor WebAssembly.
Expanding System.DirectoryServices.Protocols to Linux and macOS
We’ve been adding cross-platform support forSystem.DirectoryServices.Protocols. This includessupport for Linux andsupport for macOS. Windows support was pre-existing.
System.DirectoryServices.Protocols is a lower-level API thanSystem.DirectoryServices, and enables (or can be used to enable) more scenarios. System.DirectoryServices includes Windows-only concepts/implementations, so it was not an obvious choice to make cross-platform. Both API-sets enable controlling and interacting with a directory service server, likeLDAP orActive Directory.
System.Text.Json
System.Text.Json has beensignificantly improved in .NET 5.0 to improve performance, reliability, and to make it easier for people to adopt that are familiar withNewtonsoft.Json. It also includessupport for deserializing JSON objects to records.
If you are looking at usingSystem.Text.Json as an alternative toNewtonsoft.Json, you should check out themigration guide. The guide clarifies the relationship between these two APIs.System.Text.Json is intended to cover many of the same scenarios asNewtonsoft.Json, but it’s not intended to be a drop-in replacement for or achieve feature parity with the popular JSON library. We try to maintain a balance between performance and usability, and bias to performance in our design choices.
HttpClient extension methods
JsonSerializer extension methods are now exposed onHttpClient and greatly simplify using these two APIs together. These extension methods remove complexity and take care of a variety of scenarios for you, including handling the content stream and validating the content media type. Steve Gordon does a great job of explaining the benefits inSending and receiving JSON using HttpClient with System.Net.Http.Json.
The following example deserializes weather forecast JSON data into aForecast record, using the new
This code is compact! It is relying on top-level programs and records from C# 9 and the newGetFromJsonAsync<T>() extension method. The use offoreach andawait in such close proximity might be make you wonder if we’re going toadd support for streaming JSON objects. I really hope so.
You can try this on your own machine. The following .NET SDK commands will create a weather forecast service using the WebAPI template. It will expose the service at the following URL by default:https://localhost:5001/WeatherForecast. This is the same URL used in the sample.
rich@thundera ~ % dotnet new webapi -o webapirich@thundera ~ % cd webapi rich@thundera webapi % dotnet runMake sure you’ve rundotnet dev-certs https --trust first or the handshake between client and server won’t work. If you’re having trouble, seeTrust the ASP.NET Core HTTPS development certificate.
You can then run the previous sample.
rich@thundera ~ % git clone https://gist.github.com/3b41d7496f2d8533b2d88896bd31e764.git weather-forecastrich@thundera ~ % cd weather-forecastrich@thundera weather-forecast % dotnet run9/9/2020 12:09:19 PM; 24C; Chilly9/10/2020 12:09:19 PM; 54C; Mild9/11/2020 12:09:19 PM; -2C; Hot9/12/2020 12:09:19 PM; 24C; Cool9/13/2020 12:09:19 PM; 45C; BalmyImproved support for immutable types
There are multiple patterns for defining immutable types. Records are just the newest one.JsonSerializer now has support for immutable types.
In this example, you’ll see the serialization with an immutable struct.
using System;using System.Text.Json;using System.Text.Json.Serialization;var json = "{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"} "; var options = new JsonSerializerOptions(){ PropertyNameCaseInsensitive = true, IncludeFields = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase};var forecast = JsonSerializer.Deserialize<Forecast>(json, options);Console.WriteLine(forecast.Date);Console.WriteLine(forecast.TemperatureC);Console.WriteLine(forecast.TemperatureF);Console.WriteLine(forecast.Summary);var roundTrippedJson = JsonSerializer.Serialize<Forecast>(forecast, options);Console.WriteLine(roundTrippedJson);public struct Forecast{ public DateTime Date {get;} public int TemperatureC {get;} public int TemperatureF {get;} public string Summary {get;} [JsonConstructor] public Forecast(DateTime date, int temperatureC, int temperatureF, string summary) => (Date, TemperatureC, TemperatureF, Summary) = (date, temperatureC, temperatureF, summary);}Note: TheJsonConstructor attribute is required to specify the constructor to use with structs. With classes, if there is only a single constructor, then the attribute is not required. Same with records.
It produces the following output:
rich@thundera jsonserializerimmutabletypes % dotnet run9/6/2020 11:31:01 AM-131Scorching{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}Support for records
JsonSerializersupport for records is almost the same as what I just showed you for immutable types. The difference I want to show here is deserializing a JSON object to a record that exposes a parameterized constructor and an optional init property.
Here’s the program, including the record definition:
It produces the following output:
rich@thundera jsonserializerrecords % dotnet run{"Date":"2020-09-12T18:24:47.053821-07:00","TemperatureC":40,"Summary":"Hot!"}Forecast { Date = 9/12/2020 6:24:47 PM, TemperatureC = 40, Summary = Hot! }ImprovedDictionary<K,V> support
JsonSerializer nowsupports dictionaries with non-string keys. You can see what this looks like in the following sample. With .NET Core 3.0, this code compiles but throws aNotSupportedException.
It produces the following output.
rich@thundera jsondictionarykeys % dotnet run{"0":"zero","1":"one","2":"two","3":"three","5":"five","8":"eight","13":"thirteen","21":"twenty one","34":"thirty four","55":"fifty five"}fifty fiveSupport for fields
JsonSerializer nowsupports fields. This change was contributed by@YohDeadfall. Thanks!
You can see what this looks like in the following sample. With .NET Core 3.0,JsonSerializer fails to serialize or deserialize with types that use fields. This is a problem for existing types that have fields and cannot be changed. With this change, that’s no longer an issue.
Produces the following output:
rich@thundera jsonserializerfields % dotnet run9/6/2020 11:31:01 AM-131Scorching{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}Preserving references in JSON object graphs
JsonSerializer has addedsupport for preserving (circular) references within JSON object graphs. It does this by storing IDs that can be reconstituted when a JSON string is deserialized back to objects.
Performance
JsonSerializer performance is significantly improved in .NET 5.0. Stephen Toub covered someJsonSerializer improvements in hisPerformance Improvements in .NET 5 post. I also coveredJson Performance in more detailed in the.NET 5.0 RC1 post.
Application deployment
After writing or updating an application, you need todeploy it for your users to benefit. This might be to a web server, a cloud service, or client machine, and might be the result of a CI/CD flow using a service likeAzure DevOps orGitHub Actions.
We strive to provide first-class deployment capabilities that naturally align with the application types. For .NET 5.0, we focused on improving single file applications, reducing container size for docker multi-stage builds, and providing better support for deploying ClickOnce applications with .NET Core.
Containers
We consider containers to be the most important cloud trend and have been investing significantly in this modality. We’re investing in containers in multiple ways, at multiple levels of the .NET software stack. The first is our investment in fundamentals, which is increasingly influenced by the container scenario and by developers who deploy containerized apps.
We’re making it easier to work with container orchestrators. We’ve addedOpenTelemetry support so that you cancapture distributed traces and metrics from your application.dotnet-monitor is a new tool that is intended as the primary way to access diagnostic information from a .NET process. In particular, we have started building acontainer variant of dotnet-monitor that you can use as anapplication sidecar. Last, we are buildingdotnet/tye as way to improve microservices developer productivity, both for development and deploying to a Kubernetes environment.
The .NET runtime now hassupport for cgroup v2, which we expect will become an important container-related API beyond 2020. Docker currently uses cgroup v1 (which is already supported by .NET). In comparison, cgroup v2 is simpler, more efficient, and more secure than cgroup v1. You can learn more aboutcgroup and Docker resource limits from our 2019 Docker update. Linux distros and containers runtimes are in theprocess of adding support for cgroup v2. .NET 5.0 will work correctly in cgroup v2 environments once they become more common. Credit toOmair Majid, who supports .NET at Red Hat.
We’re nowpublishing Windows Server Core images, in addition to Nano Server. We added Server Core because we heard feedback from customers who wanted a .NET image that was fully compatible with Windows Server. If you need that, then this new image is for you. It’s supported for the combination of: Windows Server 2019 Long-Term Servicing Channel (LTSC), .NET 5.0, and x64. We’ve made other changes thatreduce the size of Windows Server Core images. Those improvements make a big difference but were made after Windows Server 2019 was released. They will, however, benefit the next Windows Server LTSC release.
As part of the move to “.NET” as the product name, we’re now publishing .NET Core 2.1, 3.1 and .NET 5.0 images to themcr.microsoft.com/dotnet family of repos, instead ofmcr.microsoft.com/dotnet/core. We will continue dual publishing .NET Core 2.1 and 3.1 to the previous location while those versions are supported. .NET 5.0 images will only be published to the new locations. Please update yourFROM statements and scripts accordingly.
As part of .NET 5.0, were-based the SDK image on top of the ASP.NET image instead ofbuildpack-deps to dramatically reduces the size of the aggregate images you pull in multi-stage build scenarios.
This change has the following benefit for multi-stage builds, with a sampleDockerfile:
Multi-stage build costs withUbuntu 20.04 Focal:
| Pull Image | Before | After |
|---|---|---|
sdk:5.0-focal | 268 MB | 232 MB |
aspnet:5.0-focal | 64 MB | 10 KB (manifest only) |
Net download savings: 100 MB (-30%)
Multi-stage build costs withDebian 10 Buster:
| Pull Image | Before | After |
|---|---|---|
sdk:5.0 | 280 MB | 218 MB |
aspnet:5.0 | 84 MB | 4 KB (manifest only) |
Net download savings: 146 MB (-40%)
Seedotnet/dotnet-docker #1814 for more detailed information.
This change helps multi-stage builds, where thesdk and theaspnet orruntime image you are targeting are the same version (we expect that this is the common case). With this change, theaspnet pull (for example), will be a no-op, because you will have pulled theaspnet layers via the initialsdk pull.
We made similar changes forAlpine and Nano Server. There is nobuildpack-deps image for either Alpine or Nano Server. However, thesdk images for Alpine and Nano Server were not previously built on top of the ASP.NET image. We fixed that. You will see significant size wins for Alpine and Nano Server as well with 5.0, for multi-stage builds.
Single file applications
Single file applications are published and deployed as asingle file. The app and its dependencies are all included within that file. When the app is run, the dependencies are loaded directly from that file into memory (with no performance penalty).
In .NET 5.0, single file apps are primarily focused on Linux (more on that later). They can be either framework-dependent or self-contained. Framework-dependent single file apps can be very small, by relying on a globally-installed .NET runtime. Self-contained single-file apps are larger (due to carrying the runtime), but do not require installation of the .NET runtime as an installation pre-step and will just work as a result. In general, framework-dependent is good for development and enterprise environments, while self-contained is often a better choice for ISVs.
We produced a version of single-file apps with .NET Core 3.1. It packages binaries into a single file for deployment and then unpacks those files to a temporary directory to load and execute them. There may be some scenarios where this approach is better, but we expect that the solution we’ve built for 5.0 will be preferred and a welcome improvement.
We had multiple hurdles to overcome to create a true single-file solution. Key tasks were creating a more sophisticated application bundler and teaching the runtime to load assemblies out of binary resources. We also ran into some hurdles that we could not clear.
On all platforms, we have a component called “apphost”. This is the file that becomes your executable, for examplemyapp.exe on Windows or./myapp on Unix-based platforms. For single file apps we created a new apphost we call “superhost”. It has the same role as the regular apphost, but also includes a statically-linked copy of the runtime. The superhost is a fundamental design point of our single file approach. This model is the one we use on Linux with .NET 5.0. We were not able to implement this approach on Windows or macOS, due to various operating system constraints. We do not have a superhost on Windows or macOS. On those operating systems, the native runtime binaries (~3 of them) sit beside the single file app (resulting in “not single file”). We’ll revisit this situation in .NET 6.0, however, we expect the problems we ran into to remain challenging.
You can use the following commands to produce single-file apps.
- Framework-dependent single-file app:
dotnet publish -r linux-x64 --self-contained false /p:PublishSingleFile=true
- Self-contained single-file app:
dotnet publish -r linux-x64 --self-contained true /p:PublishSingleFile=true
You can also configure single file publishing with a project file.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> <!-- The OS and CPU type you are targeting --> <RuntimeIdentifier>linux-x64</RuntimeIdentifier> <!-- Determine self-contained or framework-dependent --> <SelfContained>true</SelfContained> <!-- Enable single file --> <PublishSingleFile>true</PublishSingleFile> </PropertyGroup></Project>You can experiment withassembly trimming to reduce the size of your application. It can break apps, by over-trimming, so it is recommended to test your app thoroughly after using this feature. Assembly trimming also removes ahead-of-time-compiled read-to-run native code (for the assemblies that are trimmed), which is there primarily for performance. You will want to test your application for performance after trimming. You can ready-to-run-compile your app after trimmng by usingPublishReadyToRun property (and setting totrue).
Notes:
- Apps are OS and architecture-specific. You need to publish for each configuration (Linux x64, Linux Arm64, Windows x64, …).
- Configuration files (like
*.runtimeconfig.json) are included in the single file. You can place an additional config file beside the single file, if needed (possibly for testing). .pdbfiles are not included in the single file by default. You can enable PDB embedding with the<DebugType>embed</DebugType>property.- The
IncludeNativeLibrariesForSelfExtractproperty can be used toembed native runtime binaries, on Windows and macOS, however, they have to be unpacked to temporary storage at runtime. This feature is not recommended for genereal use.
ClickOnce
ClickOnce has been a popular .NET deployment option for many years. It’s now supported for .NET Core 3.1 and .NET 5.0 Windows apps. We knew that many people would want to use ClickOnce for application deployment when we added Windows Forms and WPF support to .NET Core 3.0. In the past year, the .NET and Visual Studio teams worked together to enable ClickOnce publishing, both at the command line and in Visual Studio.
We had two goals from the start of the project:
- Enable a familiar experience for ClickOnce in Visual Studio.
- Enable a modern CI/CD for ClickOnce publishing with command-line flows, with either MSBuild or the Mage tool.
It’s easiest to show you the experience in pictures.
Let’s start with the Visual Studio experience, which is centered around project publishing.

The primary deployment model we’re currently supporting isframework dependent apps. It is easy to take a dependency on the .NET Desktop Runtime (that’s the one that contains WPF and Windows Forms). Your ClickOnce installer will install the .NET runtime on user machines if it is needed. We also intend to support self-contained and single file apps.

You might wonder if you can still be able to take advantage of ClickOnce offline and updating features. Yes, you can.

The big change withMage is that it is now a .NET tool, distributed on NuGet. That means you don’t need to install anything special on your machine. You just need the .NET 5.0 SDK and then you can install Mage as a .NET tool. You can use it to publish .NET Framework apps as well, however, SHA1 signing and partial trust support have been removed.
The Mage installation command follows:
dotnet tool install -g Microsoft.DotNet.MageAfter you’ve produced and distributed your ClickOnce installer, your users will see the familiar ClickOnce installation dialogs.

Your users will see the update dialog when you make updates available.

Closing
.NET 5.0 is another big release that should improve many aspects of your use with .NET. We have enabled a broad set of improvements, ranging from single file applications, to performance, to Json serialization usability to Arm64 enablement. While today may be your first day with .NET 5.0, we’ve been running .NET 5.0 in production at Microsoft for months. We have confidence that it is ready for you to use, to run your business and power your apps. The new language improvements in C# 9 and F# 5 should make your code more expressive and easier to write. .NET 5.0 is also a great choice for your existing apps. In many cases, you can upgrade without much effort.
If you’re interested in performance, you may be interested in our progress with theTechEmpower benchmarks. Looking back, you can see that.NET Core 3.1 is doing pretty well with round 19, the latest round. We’re looking forward to seeing.NET 5.0 in the upcoming round 20. The new ranking will be something to watch out for when round 20 is finalized and published.
The improvements in .NET 5.0 are the result of efforts by many people, working collaboratively across the world and in many time zones, on GitHub. Thanks to everyone who contributed to this release. And don’t worry, there are lots of opportunities to contribute. The .NET 5.0 release has come to a close, butthe next release has already started.
Author
Richard Lander is a Principal Program Manager on the .NET Core team. He works on making .NET Core work great in memory-limited Docker containers, on ARM hardware like the Raspberry Pi, and enabling GPIO programming and IoT scenarios. He is part of the design team that defines new .NET runtime capabilities and features. He enjoys British rock and Doctor Who. He grew up in Canada and New Zealand.
116 comments
Discussion is closed.Login to edit/delete existing comments.
Ernie Salazar For ClickOnce I have a question about migrating an existing project. If we migrate an application in .net framework that deploys with CO to .net core or .net 5, will the built CO package continue to be recognized as an update to existing client installations? Or does it require a full reinstall/redpolyment to the users machines?
S T As usual, Microsoft cant be bothered to answer anyone’s questions. Nothing ever changes in these forums. – )
Manoj Kumar Is .net 5.0 support Microsoft POS For .Net to access hardware peripherals, currently we are using pos for .net in .net framework,
is there any affect on upgrading to 5.0?Akash Bagh Read moreI wanted to create a controller in a C# library and consume in all api's which i create by consuming that library so that we do not have to create the end point in every solution which we need for devops activity
C# Library 5.0 with a controller in it
Web api .net core 5.0 by consuming that library
Challenge is in library when we search for Microsoft.AspNetCore.Mvc it is not of .net 5.0 version it is 2.2.0, I am sure there wont be backward compatibility issues, But is there any plan to release 5.0.0.0 version ?
Read lessI wanted to create a controller in a C# library and consume in all api’s which i create by consuming that library so that we do not have to create the end point in every solution which we need for devops activity
C# Library 5.0 with a controller in it
Web api .net core 5.0 by consuming that library
Challenge is in library when we search for Microsoft.AspNetCore.Mvc it is not of .net 5.0 version it is 2.2.0, I am sure there wont be backward compatibility issues, But is there any plan to release 5.0.0.0 version ?
Gavin Williams Are there project templates for .Net 5 (without using a UI framework such as WinUI, WPF or Winforms)?
Gavin Williams Does .Net 5 give us access to a raw window and swapchain ala CoreWindow from UWP?
Here’s what I’m after …
I want to create a swapchain for the window without any xaml.
SharpDX has the following technique to construct a swapchain …
using (var windowAsCom = new ComObject(coreWindow)) { tempSwapChain = new SwapChain1(CoreGraphics.dxgiFactory, CoreGraphics.Device3d, windowAsCom, ref SwapChainDesc);
Can .Net 5 / WinUI provide a ComObject for this call?
silkfire Type matching withnot gives a compiler error, is this intended?
if (element is not NoteElement noteElement){ // In case it's a pause element we have only just wait desired time. Thread.Sleep(durationInMilliseconds);}CS8780 A variable may not be declared within a ‘not’ or an ‘or’ pattern.
ASHOKKUMAR SEERANGAN I need to convert a large web forms product to .NET 5. How can I convert?. Please throw some ideas. It will be very helpful to me.
Gavin Williams Really exciting stuff. Can’t wait for proper UWP integration.
In regards to the WinRT interop, can you please elaborate why you then go on to to introduce another technology .. Native Exports? How does it differ from CSWinRT interop? I’ve always seen the goal of C++/CX as a total solution to C# / C++ interop – with natural and easy interop. Obviously that’s been unattainable. But why introduce yet another project in addition to the CsWinRT tool? Is interop destined to never be solved?
Jay O'Brien I upgraded. When I choose myproject.sin, it still shows 4.52 as my .Net Framework. I went back as myproject now shows as a folder in my list of recent projects. I clicked on it and it came up. Nothing happened when I right clicked myproject (normally it had the page that showed Net framework. I finally clicked on about and it says .NET Framework Version 4.8.04084. Other options are not available on the menu. For example, none of build or publish options are under “Build”.


