We are excited to release.NET 6 Preview 4. We are now about halfway through the.NET 6 release. Now is a good time to check again. Full range of NET6. Many of the features are close to final form, while others will be available soon as the building blocks for release are in place. Preview 4 lays a solid foundation for delivering the final.NET 6 build in November, with full functionality and experience. If you haven’t tried.NET 6 in your environment, you can now use Pull.

Speaking of the final version, we now have a date! It’s scheduled for November 9-11. NET the Conf. 2021. We will be releasing.NET 6 on the 9th, with many in-depth talks and presentations that tell you all about.NET 6.

You can download.NET 6 Preview version 4 for Linux, macOS, and Windows.

  • Setup and binaries

  • Container mirror

  • Linux software package

  • Release notes

  • Known problems

  • GitHub issue tracking

See the ASP.NET Core and EF Core posts for more details on the new capabilities for the Web and data access scenarios. There is also a new.NET MAUI post describing the new client application experience, and a hot reload post describing new ways to improve developer productivity.

.NET 6 has been tested with Visual Studio 16.11 and Visual Studio for Mac 8.9. If you want to try.NET 6 in Visual Studio, we recommend that you use these versions.

Build 2021

The Microsoft Build conference has been held. You’ll definitely want to check out these talks, which will contain a lot of discussion and demonstrations about.NET 6, showing you what’s new and what’s possible now.

  • The future of.net modern application development

  • An in-depth look at.NET 6: What’s New and what’s Coming

  • .NET team “Consulting experts”

The.net six theme

We started planning.net 6 on GitHub in late 2020. We identified eight themes across a broad range of topics, including industry scenarios, support, and education. These topics represent between half and three-quarters of our publishing efforts. There are many projects that don’t rise to the level of a theme, or are significant but not a theme (such as support for Apple Silicon devices).

Here are the.NET 6 topics, each one summarized in one sentence. They are listed in the same order as they appear in themesof.net.

  • .NET appeals to new developers and students – offering a deliberately simplified experience in Visual Studio products, including clear documentation, simpler code models, and fewer files and concepts, as well as an intuitive path to deploy artifacts to test and production environments.

  • .NET has an outstanding client application development experience – providing a cross-platform client application base that seamlessly meets the needs of desktop, mobile, and Web developers and builds and extends on existing application types such as Blazor and Xamarin.

  • .NET is recognized as a compelling framework for building cloud native applications —— provides basic cloud native functionality primarily for performance and observability, improved integration with cloud native and container ecosystems, and a Cloud Native component (YARP) that shows a lot. NET value and key cloud use cases.

  • Enterprise and LTS – provides simpler, more predictable models for combining.NET with mission-critical applications and better meeting the needs of large enterprise and government customers.

  • Develop the.NET ecosystem by improving quality, confidence, and support —— build long-term community partnerships that aim to bring community developers to a level similar to Microsoft’s and (on the other hand) provide new features and experiences that make it easier for enterprise developers to rely on libraries in community open source projects, Community open source projects are not necessarily affiliated with or supported by large companies.

  • Improve in-loop performance for.NET developers —— Improve developer productivity, including improved build performance, hot restarts, and hot overloads.

  • Improved startup and throughput with runtime Execution Information (PGO) – Provides a new model based on runtime information to improve performance for faster startup, higher throughput, and smaller binaries.

  • Meet developers’ expectations – make improvements across the.NET product based on feedback and enable new solutions with existing functionality.

The following posts discuss some of these topics in more detail:

  • .NET 6 Preview version 1

  • .NET 6 Preview 2

  • Dialogue about PGO

Unified.NET platform

We’ve talked a lot about.NET unity in past posts and conferences, but it’s missing from the topic. Platform unity is built into everything we do, and we don’t need our own theme. One can think of it as a larger theme than the ones listed. It runs through multiple themes and is the basic assumption for the team to move forward.

The inner loop performance project is a good example. It assumes that.NET 6 applications all share the same foundation, such as using the same build system and libraries. If there are technical differences, such as using different runtimes (CoreCLR or Mono) or code generation technologies (AOT or JIT), we take these into account and provide a pragmatic and appropriate experience, with a preference for no observable differences in experience. The EventPipe project is another similar example.

Product confidence

We will soon begin releasing a “live” version of production support. Our current target is August. Our development model is oriented towards enabling production workloads, even though we are working on all the topics just mentioned.

Product confidence begins at dotnet.microsoft.com. Since Preview 1, it has run half the site load on.NET 6. Although small, it is a mission-critical site for our team and we take it very seriously. .NET 6 has been working for us like a champion.

We also worked with the Microsoft team that deployed the production application on the.NET preview. They did so to take advantage of new.NET features early. These teams are always looking for opportunities to reduce cloud hosting costs, and deploying new.NET versions has proven to be one of the most efficient and labor-intensive approaches. These teams provide us with early feedback to help ensure that new features are ready for global production. They also significantly influence the final feature shape because they are our first production users.

All this early hands-on testing with real applications leads us to believe that.NET 6 will be ready to run your application.

The rest of the article is devoted to the new features in Preview 4.

Tools: Use Visual Studio debugger and dotnet CLI for hot overload

Hot reloading is a new experience that allows you to edit an application’s source code while it is running, without having to manually pause the application or click a breakpoint. Hot reloading improves developer productivity by reducing the number of times a running application needs to be restarted.

In this release, hot reloads are available for many types of applications, such as WPF, Windows Forms, WinUI, ASP.NET, console applications, and other frameworks that run on top of the CoreCLR runtime. We are also working on bringing this technology to WebAssembly, iOS, and Android applications that run on Mono, but this will still show up (in a later preview).

To begin testing this feature, install Visual Studio 2019 version 16.11 Preview version 1 and launch your application using the Visual Studio debugger (F5). With the application running, you can now use the new options to change the code and apply them using the new “Apply Code Changes” button, as shown in the figure below.

Hot overloads are also available through the Dotnet monitoring tool. Preview 4 includes several fixes to improve the experience.

If you want to learn more about hot reloading, you can read. NET hot overload introduction.

IAsyncEnumerable support for System.text. Json

IAsyncEnumerable is an important feature added with.net Core 3.0 and C# 8. New enhancements support (de) serialization of System.text. Json using an IAsyncEnumerable object.

The following example uses a stream as a representation of any asynchronous data source. The source can be a file on the local machine, or the result of a database query or a Web service API call.

Flow serialization

Json now supports serializing the IAsyncEnumerable value into a Json array, as shown in the following example.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

static async IAsyncEnumerable<int> PrintNumbers(int n)
{
    for (int i = 0; i < n; i++) yield return i;
}

using Stream stream = Console.OpenStandardOutput();
var data = new { Data = PrintNumbers(3)};await JsonSerializer.SerializeAsync(stream, data); // prints {"Data":[0,1,2]}
Copy the code

The IAsyncEnumerable value supports only the asynchronous serialization method. Attempting to serialize using a synchronous method will result in a NotSupportedException being thrown.

Stream deserialization

Streaming deserialization requires a new API that returns IAsyncEnumerable. We added the JsonSerializer DeserializeAsyncEnumerable method, as shown in the following example.

using System;
using System.IO;
using System.Text;
using System.Text.Json;

var stream = new MemoryStream(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));
await foreach (int item in JsonSerializer.DeserializeAsyncEnumerable<int>(stream))
{
    Console.WriteLine(item);
}
Copy the code

This example will deserialize elements on demand and is useful when working with particularly large data streams. It only supports reading from JSON arrays at the root level, although it can be expanded in the future based on feedback.

The existing DeserializeAsync method nominally supports IAsyncEnumerable, but within the scope of its non-streaming method signature. It must return the final result as a single value, as shown in the following example.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;

var stream = new MemoryStream(Encoding.UTF8.GetBytes(@ "{" "Data ":" [0,1,2,3,4]}"));
var result = await JsonSerializer.DeserializeAsync<MyPoco>(stream);
await foreach (int item in result.Data)
{
    Console.WriteLine(item);
}

public class MyPoco
{
    public IAsyncEnumerable<int> Data { get; set; }}Copy the code

In this example, the deserializer buffers all the IAsyncEnumerable contents in memory before returning the deserialized object. This is because the deserializer needs to consume the entire JSON value before returning the result.

System.text. Json: Writable DOM functionality

Writable JSON DOM functionality adds a new simple and efficient programming model to System.text. JSON. This new API is attractive because it avoids the complexities and rituals of serialization and the traditional costs of DOM.

This new API has the following benefits:

  • A lightweight alternative to serialization in cases where POCO types are not possible or desired, or when the JSON schema is fluid and must be checked.

  • Allows effective modification of subsets of trees. For example, you can efficiently navigate to a subpart of a large JSON tree and read an array or deserialize a POCO from that subpart. LINQ can also be used with it.

  • C# dynamic keywords are allowed, which allows for a loosely typed, more script-like model.

We are looking for feedback on support dynamics. If dynamic support is important to you, please give us your feedback.

More details are provided in dotnet/ Runtime #6098.

Writable DOM API

The writable DOM exposes the following types.

namespace System.Text.Json.Node
{
    public abstract class JsonNode{... };public sealed class JsonObject : JsonNode.IDictionary<string.JsonNode? > {... }public sealed class JsonArray : JsonNode.IList<JsonNode? > {... };public abstract class JsonValue : JsonNode{... }; }Copy the code

The sample code

The following example demonstrates the new programming model.

// Parse a JSON object
    JsonNode jNode = JsonNode.Parse("{"MyProperty": 42}");
    int value = (int)jNode["MyProperty"];
    Debug.Assert(value= =42);
    // or
    value = jNode["MyProperty"].GetValue<int> (); Debug.Assert(value= =42);

    // Parse a JSON array
    jNode = JsonNode.Parse("Final three [10]");
    value = (int)jNode[1];
    Debug.Assert(value= =11);
    // or
    value = jNode[1].GetValue<int> (); Debug.Assert(value= =11);

    // Create a new JsonObject using object initializers and array params
    var jObject = new JsonObject
    {
        ["MyChildObject"] = new JsonObject
        {
            ["MyProperty"] = "Hello"["MyArray"] = new JsonArray(10.11.12)}};// Obtain the JSON from the new JsonObject
    string json = jObject.ToJsonString();
    Console.WriteLine(json); / / {" MyChildObject ": {" MyProperty" : "Hello," "MyArray on" : final three [10]}}

    // Indexers for property names and array elements are supported and can be chained
    Debug.Assert(jObject["MyChildObject"] ["MyArray"] [1].GetValue<int= = > ()11);
Copy the code

Microsoft. Extensions. Logging source code generator at compile time

.NET 6 introduces the LoggerMessageAttribute type. This property is Microsoft. Extensions. Part of the Logging namespace, use, it will generate performant Logging API. Source-generated logging support is designed to provide a highly available and high-performance logging solution for modern.NET applications. The automatically generated source code relies on the ILogger interface and loggermessage.define functionality.

When the LoggerMessageAttribute is used for a partial logging method, the source generator is triggered. When triggered, it can either automatically generate the implementation of the partial method it is decorating, or produce a compile-time diagnosis with a prompt for proper usage. Compile-time logging solutions are generally much faster at run time than existing logging methods. It does this by minimizing packing, temporary allocation, and copying.

Manually using the Loggermessage.define API directly has the following benefits:

  • Shorter and simpler syntax: Declarative properties are used instead of code boilerplate.

  • Guide the developer experience: The generator gives warnings to help the developer do the right thing.

  • Any number of log parameters are supported. Loggermessage. Define supports a maximum of six messages.

  • Supports dynamic log levels. Loggermessage.define alone is not possible.

  • If you want to track improvements and known issues, see dotnet/runtime#52549.

Basic usage

To use LoggerMessageAttribute, the consumer class and method need to be partial. The code generator fires at compile time and generates the implementation of a partial method.

public static partial class Log{[LoggerMessage(EventId = 0, Level = LogLevel.Critical, Message = "Could not open socket to `{hostName}`")]
    public static partial void CouldNotOpenSocket(ILogger logger, string hostName);
}
Copy the code

In the previous example, the logging method was static and the logging level was specified in the property definition. When this property is used in a static context, an ILogger instance is required as an argument. You can also choose to use this property in a non-static context. For more examples and usage scenarios, visit the documentation for compile-time log source generators.

System.Linq enhancements

New System.linq API for community requests and contributions added.

Enumerable support for index and range parameters

The Enumerable.ElementAt method now accepts the index at the end of the Enumerable object, as shown in the following example.

Enumerable.Range(1.10).ElementAt(\^2); // returns 9
Copy the code

Added an Enumerable.Take overload that takes a Range argument. It simplifies slicing an enumerable sequence:

  • source.Take(.. 3) instead of source.take (3)

  • source.Take(3..) Rather than the source. The Skip (3)

  • source.Take(2.. 7) instead of source.take (7).Skip(2)

  • source.Take(^3..) Rather than the source. TakeLast (3)

  • source.Take(.. ^3) instead of source.skiplast (3)

  • source.Take(^7.. ^3) instead of source.takelast (7).skiplast (3).

Thanks to @Dixin for contributing to the implementation.

TryGetNonEnumeratedCount

The trygetNonEnumereratedCount method attempts to get the enumerable count from the source without forcing an enumeration. This approach is useful in cases where it is useful to preallocate buffers before enumeration, as shown in the following example.

List<T> buffer = source.TryGetNonEnumeratedCount(out int count) ? new List<T>(capacity: count) : new List<T>();
foreach (T item in source)
{
    buffer.Add(item);
}
Copy the code

TryGetNonEnumeratedCount checks for sources that implement ICollection/ICollection or take advantage of some internal optimizations that Linq employs.

DistinctBy/UnionBy/IntersectBy/ExceptBy

A new variant has been added to the set operation that allows you to specify equality using the key selector function, as shown in the following example.

Enumerable.Range(1.20).DistinctBy(x => x % 3); / / {1, 2, 3}

var first = new (string Name, int Age)[] { ("Francis".20), ("Lindsey".30), ("Ashley".40)};var second = new (string Name, int Age)[] { ("Claire".30), ("Pat".30), ("Drew".33)}; first.UnionBy(second, person => person.Age);// { ("Francis", 20), ("Lindsey", 30), ("Ashley", 40), ("Drew", 33) }
Copy the code

MaxBy/MinBy

The MaxBy and MinBy methods allow you to find the maximum or minimum element using the key selector, as shown in the following example.

var people = new (string Name, int Age)[] { ("Francis".20), ("Lindsey".30), ("Ashley".40)}; people.MaxBy(person => person.Age);// ("Ashley", 40)
Copy the code

Chunk

Chunk can be used to slice enumerable sources into fixed-size slices, as shown in the following example.

IEnumerable<int[]> chunks = Enumerable.Range(0.10).Chunk(size: 3); // {{0,1,2}, {3,4,5}, {6,7,8}, {9}}
Copy the code

Thanks to Robert Andersson for his contribution to the implementation.

FirstOrDefault LastOrDefault/SingleOrDefault override the default parameters

If the source enumeration is empty, the existing FirstOrDefault/LastOrDefault SingleOrDefault method returns the default (T). A new overload has been added to accept the default argument to return in this case, as shown in the following example.

Enumerable.Empty<int>().SingleOrDefault(- 1); // returns -1
Copy the code

Thanks to @FoxTrek64 for contributing to the implementation.

A Zip overload that accepts three enumerations

The Zip method now supports combining three enumerable items, as shown in the following example.

var xs = Enumerable.Range(1.10);
var ys = xs.Select(x => x.ToString());
var zs = xs.Select(x => x % 2= =0);

foreach ((int x, string y, bool z) in Enumerable.Zip(xs,ys,zs))
{
}
Copy the code

Thanks to Huo Yaoyuan for his contribution to the implementation.

Significantly improves FileStream performance on Windows

FileStream has been rewritten in.NET 6 for higher performance and reliability on Windows.

The rewrite project has gone through five PR phases:

  • FileStreamStrategy is introduced as the first step in FileStream rewriting

  • FileStream rewrites the second part

  • File flow optimization

  • FileStream rewrite: use IValueTaskSource instead of TaskCompletionSource

  • FileStream rewrite: in AsyncWindowsFileStreamStrategy ValueTaskSource cache

The end result is that FileStream will never block when created for asynchronous IO on Windows. This is a major improvement. You can see this in the benchmark, as we’ll see shortly.

configuration

The first PR enables FileStream to select an implementation at run time. The most obvious benefit of this pattern is that you can switch back to the old.NET 5 implementation, which you can do using the following Settings in Runtimeconfig.json.

{
    "configProperties": {
        "System.IO.UseNet5CompatFileStream": true}}Copy the code

We plan to add an IO_uring strategy next, which takes advantage of the Linux feature of the same name in the recent kernel.

Performance benchmark

Let’s use BenchmarkDotNet to measure improvement.

public class FileStreamPerf
{
    private const int FileSize = 1_000_000; // 1 MB
    private Memory<byte> _buffer = new byte[8_000]; // 8 kB

    [GlobalSetup(Target = nameof(ReadAsync))]
    public void SetupRead() => File.WriteAllBytes("file.txt".new byte[FileSize]);

    [Benchmark]
    public async ValueTask ReadAsync()
    {
        using FileStream fileStream = new FileStream("file.txt", FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true);
        while (await fileStream.ReadAsync(_buffer) > 0) {}} [Benchmark]
    public async ValueTask WriteAsync()
    {
        using FileStream fileStream = new FileStream("file.txt", FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize: 4096, useAsync: true);
        for (int i = 0; i < FileSize / _buffer.Length; i++)
        {
            awaitfileStream.WriteAsync(_buffer); }} [GlobalCleanup]
    public void Cleanup() => File.Delete("file.txt");
}

Copy the code

Ini BenchmarkDotNet = v0.13.0, OS = Windows 10.0.18363.1500 (1909 / November2019Update/h2) 19 Intel Xeon E5-1650 v4 CPU 3.60 GHz, 1 CPU, 12 Logical and 6 physical cores.net SDK=6.0.100-preview.5.21267.9 [Host] : .net 5.0.6 (5.0.621.22011), X64 RyuJIT job-oIMCTV:.net 5.0.6 (5.0.621.22011), X64 RyuJIT job-chfnuy: .NET 6.0.0 (6.0.21.26311), X64 RyuJIT

Environment: Windows 10 with SSD drive enabled BitLocker

Results:

  • Reading 1 MB files is now two times faster and writing is four times faster.

  • Memory allocation decreased from 39 KB to 1 KB! That’s a 97.5% improvement!

These changes will provide significant improvements for FileStream users on Windows. For more details, please visit dotnet/core #6098.

Enhanced date, time, and time zone support

The following improvements have been made to the date – and time-related types.

New DateOnly and TimeOnly structures

Added date and time only structure with the following features:

  • Each represents half of a DateTime, either just the date part or just the time part.

  • DateOnly is ideal for birthdays, anniversaries and working days. It is consistent with the date type of SQL Server.

  • TimeOnly is ideal for regular meetings, alarm clocks, and weekly work hours. It is consistent with the time type of SQL Server.

  • Add an existing date/time type (DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo).

  • In the System namespace, provided in CoreLib, just like the existing related types.

Performance improvements to Datetime.utcNow

This improvement has the following benefits:

  • Fixed 2.5x performance regression for getting system time on Windows.

  • Use the Windows 5-minute slide cache of leap second data instead of getting it on each call.

Support for Windows and IANA time zones on all platforms

This improvement has the following benefits:

  • When using TimeZoneInfo. FindSystemTimeZoneById implicit conversion (github.com/dotnet/runt…).

  • By means of the new API to convert the explicit TimeZoneInfo: TryConvertIanaIdToWindowsId, TryConvertWindowsIdToIanaId

And HasIanaId (github.com/dotnet/runt…).

  • Improved cross-platform support and interoperability between systems using different time zone types.

  • The deletion requires the TimeZoneConverter OSS library. This feature is now built in.

Improved time zone display name

This improvement has the following benefits:

  • From TimeZoneInfo. GetSystemTimeZones returned to eliminate ambiguity in the display name of the list.

  • Using ICU/CLDR globalization data.

  • Unix only. Windows still uses registry data. This may change later.

other

  • The display name and standard name for the UTC time zone have been hardcoded into English and are now in the same language as the rest of the time zone data (CurrentUICulture on Unix, the OS default language on Windows).

  • Due to size limitations, the time zone display name in WASM is changed to use a non-localized IANA ID.

  • TimeZoneInfo. AdjustmentRule nested classes will be its BaseUtcOffsetDelta internal attribute is set to open, and get a new constructor BaseUtcOffsetDelta as parameters. (github.com/dotnet/runt…

  • TimeZoneInfo. AdjustmentRule also received other repair on Unix loading time zone (github.com/dotnet/runt…

CodeGen

The following improvements have been made to the RyuJIT compiler.

Contribution to the community

@Singleaccretion has been busy making the following improvements over the past few months. This is a supplement to.NET 6 Preview 3. Thank you very much!

  • Dotnet/Runtime #50373 — Do not fold double negations if the tree is a CSE candidate

  • Dotnet/Runtime #50450 — Handles helper conversions and collapse overflows in value numbers

  • Dotnet/Runtime #50702 — Delete the must-init requirement for GS cookies

  • Dotnet/Runtime #50703 — Do not confuse fgDispBasicBlocks with fgDispBasicBlocks

Dynamic PGO

The following improvements have been made to support dynamic PGO.

  • Dotnet/Runtime #51664 — Update JIT to use new “LikelyClass” records seen in PGO data processed across generations

  • Dotnet/Runtime #50213 – Better tolerance for inconsistency in edge contours

  • Dotnet/Runtime #50633 — Fixed hybrid PGO/nonPGO compilation

  • Dotnet/Runtime #50765 — modify fgExpandRunRarelyBlocks

  • Dotnet/Runtime #51593 — Modified inline sizing calculation

JIT loop optimization

The following improvements have been made to the cycle optimization.

  • Dotnet/Runtime #50982 — Summarize loop inversion

  • Dotnet/Runtime #51757 — Do not recalculate the preds list during cyclic cloning

LSRA

Linear scan register allocation (LRSA) has the following improvements.

  • Dotnet/Runtime #51281 — improved LRSA statistics to include register selection heuristics

To optimize the

  • Dotnet/Runtime #49930 — Collapses empty checks on const strings at the value number level

  • Dotnet/Runtime #50000 — Null check for initialized static read-only fields of type REF

  • Dotnet/Runtime #50112 — Do not assign string literals to potential BBJ_THROW candidates

  • Dotnet/Runtime #50644 — Enable the CSE for vectorx.create

  • Dotnet/Runtime #50806 — Discard tail calls if unexpected blocks follow

  • Dotnet/Runtime #50832 — Update Vector to support nint and Nuint

  • Dotnet/Runtime #51409 – Outlines the branches around nullstream optimization

.NET diagnostics: EventPipe for Mono and improved EventPipe performance

EventPipe is a.net cross-platform mechanism for outputting events, performance data, and counters. Starting with.NET 6, we have moved our implementation from C++ to C. With this change, Mono will also be able to use EventPipe! This means that CoreCLR and Mono will use the same event infrastructure, including the.NET diagnostic CLI tool! This change was accompanied by a small reduction in the CoreCLR:

We also made some changes to improve EventPipe throughput under load. In the first few previews, we made a series of changes that increased throughput by 2.06 times over.net 5:

  • Data collected using the EventPipeStress framework in DotNet/Diagnostics. The writer application writes events as fast as possible in 60 seconds. Record the number of successful and discarded events.

For more information, see dotnet/ Runtime #45518.

IL clipping

Warning is enabled by default

Clipping alerts tell you where clipping might remove code used at run time. These warnings were previously disabled by default because they were very noisy, mainly due to. The NET platform does not participate in tailoring as a first category solution.

We annotated most of the.net libraries (runtime libraries, not ASP.NET Core or the Windows desktop framework) so that they generate accurate clipping warnings. Therefore, we think it’s time to enable cropping warnings by default.

You can disable warnings by setting it to true. For earlier versions, you can set the same property to false to see cropping warnings.

Clipping warnings bring predictability to the clipping process and power to the developer. We will continue to annotate more.NET libraries, including ASP.NET Core in later releases. We hope the community will also improve the tailoring ecosystem by commenting more code to ensure that tailoring is safe.

More information:

  • Clipping warnings in.NET 6

  • Prepare the.NET libraries for tailoring

Default cropping mode = link

The new default clipping mode in.NET 6 is linking. Linking TrimMode allows you to crop not only unused assemblies but also unused members, resulting in significant cost savings.

In.NET 5, clipping by default tries to find and delete unreferenced assemblies. This is safer, but provides limited benefits. Now that cropping warnings are enabled by default, developers can be confident in cropping results.

As an example, let’s look at this clipping improvement by clipping one of the.NET SDK tools. I’ll use CrossGen, which is the compiler ready to run. It can be clipped with just a few clipping warnings, which the CrossGen team was able to address.

First, let’s publish CrossGen as a standalone application, without the need for tailoring. It is 80 MB (including the.NET runtime and all libraries).

Then we can try the (now old).NET 5 default clipping mode, copyUsed. The result is down to 55 MB.

The new.NET 6 default clipping mode link reduces the standalone file size further to 36MB.

We hope that the new link clipping pattern will better meet the expectations of clipping: significant savings and predictable results.

Share the model with Native AOT

We also implemented the same clipping warnings for Native AOT experiments, which should improve the Native AOT compilation experience in much the same way.

Single file release

The following improvements have been made to single-file application publishing.

Static analysis

.NET 5 added parsers for single-file publishing to warn assembly.location and other apis that behave differently in single-file packages.

For.NET 6 Preview 4, we have improved the analysis to allow custom warnings. If your API does not work in a single-file distribution, you can now mark it with the [RequiresAssemblyFiles] attribute, and a warning will appear if profiler is enabled. Adding this property will also mute all warnings related to a single file in the method, so you can use it to propagate warnings up to your public API.

When PublishSingleFile is set to true, the parser is automatically enabled for exe projects, but you can also enable it for any project by setting EnableSingleFileAnalysis to true. This may be helpful if you want to embed the library in a single file package.

The compression

Single package now support compression. This can be achieved by the attribute EnableCompressionInSingleFile is set to true to enable. At run time, the files are unzipped into memory as needed. Compression can provide significant space savings for some scenarios.

Let’s take a look at the single file distribution with and without compression used with NuGet Package Explorer.

Uncompressed: 172 MB

After compression: 71.6MB

Compression can significantly increase the startup time of applications, especially on Unix platforms (because they have copy-free fast start paths that cannot be used with compression). You should test your application after compression is enabled to see if the additional start-up costs are acceptable.

PublishReadyToRun now defaults to crossGen2

Crossgen2 is now enabled by default when publishing ReadyToRun images. Optionally, it supports the generation of composite images.

Expose the following Settings to enable you to configure the publication with code ready to run. These Settings are set to their default values.

PublishReadyToRun now defaults to crossGen2

Crossgen2 is now enabled by default when publishing ReadyToRun images. Optionally, it supports the generation of composite images.

Expose the following Settings to enable you to configure the publication with code ready to run. These Settings are set to their default values.

CLI installation for the.NET 6 SDK optional workload

.NET 6 will introduce the concept of SDK workloads that can be installed on top of.net SDKS after the fact to support a variety of scenarios. The new workloads available in Preview 4 are the.NET MAUI and Blazor WebAssembly AOT workloads.

For.net MAUI workloads, we still recommend using preview 4’s Maui-Check tool because it contains other components not yet available in Visual Studio or as a.NET SDK workload. To try out the.NET SDK experience (for iOS), run dotnet Working Install Microsoft-ios-sdK-full. After installation, you can run dotnet New ios and then run dotnet Build to create and build your project.

For Blazor WebAssembly AOT, follow the installation instructions provided by the ASP.NET blog.

Preview 4 includes.net MAUI workloads for iOS, Android, tvOS, MacOS, and MacCatalyst.

Note that the dotNet workload installation copies the workload from NuGet.org to your SDK installation, so if the SDK installation location is protected (meaning at the administrator/root location), you need to run lift /sudo.

Built-in SDK version check

To make it easier to keep track of when new versions of the SDK and runtime are available, we’ve added a new command to the.NET 6 SDK: dotnet SDK check

This will tell you what is the latest available version of the.NET SDK and.NET runtime within each feature band.

CLI Template (dotnet new)

Preview 4 introduces a new template search feature. Dotnet new –search will search NuGet.org for matching templates. During the upcoming preview, the data for this search will be updated more frequently.

The template installed in the CLI is available for CLI and Visual Studio. An earlier issue where user-installed templates were lost while installing the new SDK version has been resolved, but you need to reinstall the templates installed before.NET 6 Preview 4.

Other improvements to template installation include support for the — Interactive switch to support authorization credentials for private NuGet sources.

After installing the CLI template, you can check whether updates are available using –update-check and –update-apply. This will now reflect template updates more quickly, support NuGet sources that you define, and support — Interactive authorization credentials.

In Preview 4 and the upcoming preview release, the output of the dotnet new command will be cleaned up to focus on the information you need most. For example, dotnet new –install lists only the templates that have just been installed, not all templates.

To support these and upcoming changes to Dotnet New, we are making significant changes to the template engine API that may affect anyone who hosts the template engine. These changes will appear in preview 4 and Preview 5. If you are hosting a template engine, please contact github.com/dotnet/temp… Contact us so we can work with you to avoid or minimize disruptions.

support

.NET 6 will be released in November 2021 and will be supported for three years as a Long-term support (LTS) version. The platform matrix has been significantly expanded.

The new content is:

  • The android
  • IOS
  • Mac and Mac Catalyst for X64 and Apple Silicon (aka “M1”)
  • Windows Arm64 (especially Windows desktop)

The.NET 6 Debian container image is based on Debian 11 (” Bullseye “) and is currently being tested.

The end of the

At this point we have entered the.NET 6 version. While the November final release seems a long way off, we are close to completing feature development. Now is a good time for feedback, as the shape of the new feature is now set and we are still in active development, so it is easy to act on the feedback.

Speaking of November, book some time to watch.NET Conf 2021 between November 9 and 11. It will certainly be exciting and interesting. We will release the final.NET 6 release on November 9, along with a longer blog post than this one.

Looking for more to read? You can check out our new dialogue series. There are many detailed insights into the new features of.NET 6. Any technical questions, please ask at Microsoft Q&A.

We hope you enjoy trial Preview 4.