Announcing .NET Core 3.0 Preview 6



Today, we are announcing .NET Core 3.0 Preview 6. It includes updates for compiling assemblies for improved startup, optimizing applications for size with linker and EventPipe improvements. We’ve also released new Docker images for Alpine on ARM64.

Download .NET Core 3.0 Preview 6 right now on Windows, macOS and Linux.

Release notes have been published at dotnet/core. An API diff between Preview 5 and 6 is also available.

ASP.NET Core and EF Core are also releasing updates today.

If you missed it, check out the improvements we released in .NET Core 3.0 Preview 5, from last month.

WPF and Windows Forms update

The WPF team has now completed publishing most of the WPF codebase to GitHub. In fact, they just published source for fifteen assemblies. For anyone familiar with WPF, the assembly names should be very familiar.

In some cases, tests are still on the backlog to get published at or before 3.0 GA. That said, the presence of all of this code should enable the WPF community to fully participate in making changes across WPF. It is obvious from reading some of the GitHub issues that the community has its own backlog that it has been waiting to realize. Dark theme, maybe?

Alpine Docker images

Docker images are now available for both .NET Core and ASP.NET Core on ARM64. They were previously only available for x64.

The following images can be used in a Dockerfile, or with docker pull, as demonstrated below:

  • docker pull
  • docker pull

Event Pipe improvements

Event Pipe now supports multiple sessions. This means that you can consume events with EventListener in-proc and simultaneously have out-of-process event pipe clients.

New Perf Counters added:

  • % Time in GC
  • Gen 0 Heap Size
  • Gen 1 Heap Size
  • Gen 2 Heap Size
  • LOH Heap Size
  • Allocation Rate
  • Number of assemblies loaded
  • Number of ThreadPool Threads
  • Monitor Lock Contention Rate
  • ThreadPool Work Items Queue
  • ThreadPool Completed Work Items Rate

Profiler attach is now implemented using the same Event Pipe infrastructure.

See Playing with counters from David Fowler to get an idea of what you can do with event pipe to perform your own performance investigations or just monitor application status.

See dotnet-counters to install the dotnet-counters tool.

Optimize your .NET Core apps with ReadyToRun images

You can improve the startup time of your .NET Core application by compiling your application assemblies as ReadyToRun (R2R) format. R2R is a form of ahead-of-time (AOT) compilation.

R2R binaries improve startup performance by reducing the amount of work the JIT needs to do as your application is loading. The binaries contain similar native code as what the JIT would produce, giving the JIT a bit of a vacation when performance matters most (at startup). R2R binaries are larger because they contain both intermediate language (IL) code, which is still needed for some scenarios, and the native version of the same code, to improve startup.

R2R is supported with .NET Core 3.0. It cannot be used with earlier versions of .NET Core.

Sample performance numbers

The following are performance numbers collected using a sample WPF application. The application was published as self-contained and did not use the assembly linker (covered later this post).

IL-only Application:

  • Startup time: 1.9 seconds
  • Memory usage: 69.1 MB
  • Application size: 150 MB

With ReadyToRun images:

  • Startup time: 1.3 seconds.
  • Memory usage: 55.7 MB
  • Application size: 156 MB

ReadyToRun images, explained

You can R2R compile both libraries and application binaries. At present, libraries can only be R2R compiled as part of an application, not for delivery as a NuGet package. We’d like more feedback on whether that scenario is important.

AOT compiling assemblies has been available as a concept with .NET for a long time, going back to the .NET Framework and NGEN. NGEN has a key drawback, which is that compilation must be done on client machines, using the NGEN tool. It isn’t possible to generate NGEN images as part of your application build.

Enter .NET Core. It comes with crossgen, which produces native images in a newer format called ReadyToRun. The name describes its primary value proposition, which is that these native images can be built as part of your build and are “ready to run” without any additional work on client machines. That’s a major improvement, and also an important win for climate change.

In terms of compatibility, ReadyToRun images are similar to IL assemblies, with some key differences.

  • IL assemblies contain just IL code. They can run on any runtime that supports the given target framework for that assembly. For example a netstandard2.0 assembly can run on .NET Framework 4.6+ and .NET Core 2.0+, on any supported operating system (Windows, macOS, Linux) and architecture (Intel, ARM, 32-bit, 64-bit).
  • R2R assemblies contain IL and native code. They are compiled for a specific minimum .NET Core runtime version and runtime environment (RID). For example, a netstandard2.0 assembly might be R2R compiled for .NET Core 3.0 and Linux x64. It will only be usable in that or a compatible configuration (like .NET Core 3.1 or .NET Core 5.0, on Linux x64), because it contains native code that is only usable in that runtime environment.


The ReadyToRun compilation is a publish-only, opt-in feature. We’ve released a preview version of it with .NET Core 3.0 Preview 5.

To enable the ReadyToRun compilation, you have to:

  • Set the PublishReadyToRun property to true.
  • Publish using an explicit RuntimeIdentifier.

Note: When the application assemblies get compiled, the native code produced is platform and architecture specific (which is why you have to specify a valid RuntimeIdentifier when publishing).

Here’s an example:

And publish using the following command:

Note: The RuntimeIdentifier can also be set in the project file.

Note: ReadyToRun is currently only supported for self-contained apps. It will be enabled for framework-dependent apps in a later preview.

Native symbol generation can be enabled by setting the PublishReadyToRunEmitSymbols property to true in your project. You do not need to generate native symbols for debugging purposes. These symbols are only useful for profiling purposes.

The SDK currently supports a way to exclude certain assemblies from being compiled into ReadyToRun images. This could be useful for cases when certain assemblies do not really need to be optimized for performance. This can help reduce the size of the application. It could also be a useful workaround for cases where the ReadyToRun compiler fails to compile a certain assembly. Exclusion is done using the PublishReadyToRunExclude item group. Example:

Cross platform/architecture compilations

The ReadyToRun compiler doesn’t currently support cross-targeting. You need to compile on a given target. For example, if you want R2R images for Windows x64, you need to run the publish command on that environment.

Exceptions to this:

  • Windows x64 can be used to compiles Windows ARM32, ARM64, and x86 images.
  • Windows x86 can be used to compile Windows ARM32 images.
  • Linux x64 can be used to compile Linux ARM32 and ARM64 images.

Assembly linking

The .NET core 3.0 SDK comes with a tool that can reduce the size of apps by analyzing IL and trimming unused assemblies.

With .NET Core, it has always been possible to publish self-contained apps that include everything needed to run your code, without requiring .NET to be installed on the deployment target. In some cases, the app only requires a small subset of the framework to function and could potentially be made much smaller by including only the used libraries.

We use the IL linker to scan the IL of your application to detect which code is actually required, and then trim unused framework libraries. This can significantly reduce the size of some apps. Typically, small tool-like console apps benefit the most as they tend to use fairly small subsets of the framework and are usually more amenable to trimming.

To use this tool, set PublishTrimmed=true in your project and publish a self-contained app:

The publish output will include a subset of the framework libraries, depending on what the application code calls. For a helloworld app, the linker reduces the size from ~68MB to ~28MB.

Applications or frameworks (including ASP.NET Core and WPF) that use reflection or related dynamic features will often break when trimmed, because the linker doesn’t know about this dynamic behavior and usually can’t determine which framework types will be required for reflection at run time. To trim such apps, you need to tell the linker about any types needed by reflection in your code, and in any packages or frameworks that you depend on. Be sure to test your apps after trimming.

For more information about the IL Linker, see the documentation, or visit the mono/linker repo.

Note: In previous versions of .NET Core, ILLink.Tasks was shipped as an external NuGet package and provided much of the same functionality. It is no longer supported – please update to the latest 3.0 SDK and try the new experience!

Using the Linker and ReadToRun Together

The linker and ReadyToRun compiler can be used for the same application. In general, the linker makes your application smaller, and then the ready-to-run compiler will make it a bit larger again, but with a significant performance win. It is worth testing in various configurations to understand the impact of each option.

Note: dotnet/sdk #3257 prevents the linker and ReadyToRun from being used together for WPF and Windows Forms applications. We are working on fixing that as part of the .NET Core 3.0 release.

Native Hosting sample

The team recently posted a Native Hosting sample. It demonstrates a best practice approach for hosting .NET Core in a native application.

As part of .NET Core 3.0, we now expose general functionality to .NET Core native hosts that was previously only available to .NET Core managed applications through the officially provided .NET Core hosts. The functionality is primarily related to assembly loading. This functionality should make it easier to produce native hosts that can take advantage of the full feature set of .NET Core.

HTTP/2 support in HttpClient

HTTP/2 is a major revision of the HTTP protocol. Some of the notable features of HTTP/2 are support for header compression and fully multiplexed streams over the same connection. While HTTP/2 preserves HTTP’s semantics (HTTP headers, methods, etc) it is a change from HTTP/1.x in how data is framed and sent over the wire.

HttpClient now add supports for making HTTP/2 requests. While the default remains HTTP/1.1, you can opt in to using HTTP/2 by setting the version on your HTTP request message.

Alternatively, you can default to sending HTTP/2 requests by setting the DefaultRequestVersion property on HttpClient.

As a consequence of this change in framing, servers and clients need to negotiate the protocol version used. Application-Layer Protocol Negotiation (ALPN) is a TLS extension that allows the server and client negotiate the protocol version used as part of their TLS handshake. While it is possible to have prior knowledge between the server and the client on the protocol, most servers only support ALPN as the only way to establish an HTTP/2 connection. As such, HTTP/2 is negotiated by HttpClient only on a TLS connection.

In development scenarios when server and client have a priori knowledge that both will speak HTTP/2 unencrypted, you may establish an HTTP/2 connection over cleartext by setting an AppContext switch or an environment variable (DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1).


Please try out the new features. Please file issues for the bugs or any challenging experiences you find. We want the feedback! You can file feature requests, too, but they likely will need to wait to get implemented until the next release at this point.

We are now getting very close to being feature complete for .NET Core 3.0, and are now transitioning the focus of the team to the quality of the release. We’ve got a few months of bug fixing and performance work ahead. We’ll appreciate your feedback as we work through that process, too.

On that note, we will soon be switching the master branches on .NET Core repos to the next major release, likely at or shortly after the Preview 7 release (July).

Thanks for trying out .NET Core 3.0 previews. We appreciate your help. At this point, we’re focused on getting a final release in your hands.

Richard Lander

Program Manager, .NET Team

Follow Richard   

Michael DeMond 2019-06-12 10:39:44
Very nice, team.  .NET is truly where MSFT is at these days.  With Blazor on the way -- especially its server-side mode which should be marketed/promoted more -- I'm starting to get the warm n' fuzzies around application development again.  ReadyToRun, indeed. 
LOST _ 2019-06-12 11:14:26
I honestly think NGen is in many ways a better solution to native precompilation for two major reasons: 1. It simplifies my job as a developer: now I can focus on features and high-level performance of my app, no need to bother with building for a myriad of different platforms, which is one of the major points in targeting CLR vs native in the first place. 2. Client-side NGen can detect additional CPU features like AVX or even specific processor model, and enable related optimizations, yielding better improvements at both startup and runtime.
Ismail Demir 2019-06-12 13:46:38
R.I.P VB.Net Thank You!
bat forest 2019-06-12 19:17:15
About 30MB on windows,there is still gap with C++ and Go,although the latter has no reflection.Hope everything better.
Mahdi Hosseini 2019-06-12 22:29:32
hi tnx for your great work. Is it possible to do PublishReadyToRun or p:PublishSingleFile in Publish window? I mean, we do not use the command line and get inside Visual Studio without editing project file. Do you have any plans for the future? Or should we keep all these codes?
Stig Nielsson
Stig Nielsson 2019-06-13 02:08:04
Great news. And great that we apparently now get a .Net Core 5.0 in addition to .Net 5.0 :-)
Mike Marynowski 2019-06-13 02:54:38
When is it anticipated that the XAML designer will be functional in Blend/VS when working on .NET Core projects?
Jefferson Motta 2019-06-13 07:25:10
Oh boy. Very nice that .NET Framework is dead and will not be possible call from .NET Core. But for a while, about 10years I guess (the time to the world migrate .NF to .NC) I found a way to call .NET Framework from .NET Core, and works fine. I guess .NET Core 5 will be called .NET One, is that?
monkey noises 2019-06-13 12:59:02
If an image is made R2R for Windows x86...and that assembly somehow ends up on a Linux platform....does it fall back to using the IL inside and give to the JIT....or fail to execute at all? Can R2R assemblies contain multiple R2R platform targets? that an "agile" assembly  Can an R2R assembly/app be told on purpose not to use its native R2R image code (even though its running on an R2R target platform), and to fall back to using the IL with the JIT, etcThe above cases would make distribution/installation/management of assemblies only 1 installer/xcopy/distribution needs to be maintained.
Geovanny Fiallo 2019-06-13 17:17:11
Hi Richard, this are good news! Maybe you know when we can use .NET Core 3 to make production ready applications? Regards
James Rolfe 2019-06-13 21:30:13
Any plans to port more members of "Microsoft.VisualBasic.dll" to .NET Core ? The portability analysis tool indicates that my WPF projects are still not 100% portable to .NET Core because of the heavy use of "MsgBox". The .NET Framework version of "MsgBox" function depends on Winform. But you can inline the implementation of "MessageBox.Show" (PInvoke MessageBoxW) to "MsgBox" to resolve the dependency problem.
Michael Lam
Michael Lam 2019-06-14 01:00:49
You've got a typo in one of your headers: "Using the Linker and ReadToRun Together"
Vadim Peretokin 2019-06-14 08:04:58
"With .NET Core, it has always been possible to publish self-contained apps that include everything needed to run your code, without requiring .NET to be installed on the deployment target." I'm confused, wasn't PublishSingleFile only announced in preview 5? What option is this sentence referring to?
Hall, Trevor 2019-06-14 10:46:45
Will there be support (in MsTest) for writing unit tests in .Net core 3.0 and C# for "user controls" written in either winforms or WPF? I have a large number of test cases which create Win forms controls, WPF canvases etc. all of which run in all versions of "Framework 4.6 or 4.7" but all of which fail when using "core 3", even at preview 6. If it is supported, where can I find an example? Maybe I can copy something from such an example.
Sabarinath Gopalan 2019-06-14 13:31:26
Nice.. ReadyToRun.  I think this will avoid the cold start time in serverless application.
Diego Mendes 2019-06-15 00:44:22
Http2 settings should be more specific, Version and DefaultRequestVersion doesn't make it suggestive enough that you are setting the protocol version. Also it seems that applies only to requests, where technically it applies to the underlying connection used by requests and responses.
Glenn Puchtel
Glenn Puchtel 2019-06-21 12:03:42
I have the following API entry-point: [HttpPost]public async Task<ActionResult<Message>> Post([FromBody] JObject value){ } I updated to 3.0.0-preview6.19307.2, and (without changing any code) I get the following exception : System.MissingMethodException: Method not found: 'Void Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream..ctor(System.IO.Stream, Int32)'.at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)at Microsoft.AspNetCore.Mvc.Formatters.TextInputFormatter.ReadRequestBodyAsync(InputFormatterContext context)at Microsoft.AspNetCore.Mvc.Formatters.InputFormatter.ReadAsync(InputFormatterContext context)at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()--- End of stack trace from previous location where exception was thrown ---at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Joey . 2019-06-21 12:43:34
Any plans to also include the License Compiler lc.exe and its MSBuild targets? Right now that's one part that we stumbled over as missing while porting our commercial WinForms/WPF library to .NET Core.
James Wil
James Wil 2019-06-21 17:44:44
R2R doesn't look that promising tbh.. this is just dodging the bullet, C# needs an AOT compiler asap for fast startup by default! performance as a feature, not as an option, please!