We are very happy to release .NET 6 Preview 4. We are now about halfway through the .NET 6 release. Now is a good time to view the full range of .NET6 again. Many features are close to final form, while others will be launched soon because the basic building blocks for release are already in place. Preview 4 lays a solid foundation for delivering the final .NET 6 build in November, and provides a complete functionality and experience. If you haven't tried .NET 6 in your environment, you can use pull now.
Speaking of the final version, we now have a date! Expected in November 9 to 11 of the .NET Conf 2021 . We will release .NET 6 on the 9th, which contains many in-depth talks and demos to tell you all about .NET 6.
.NET 6 Preview 4 for Linux, macOS and Windows.
- installer and binary file
- container image
- Linux software package
- Release Notes
- Known issues
- GitHub issue tracking
For more details on the new features of the web and data access solutions, please refer to the ASP.NET Core and EF Core posts. There is also a new .NET MAUI describing the new client application experience, and a hot reload post describing new ways to improve developer productivity.
.NET 6 has been with 160f2951813159 Visual Studio 16.11 and Visual Studio for Mac 8.9 . If you want Visual Studio , we recommend that you use these versions.
Build 2021
The Microsoft Build conference has been held. You will definitely want to watch these talks, which will contain a lot of discussions and demonstrations about .NET 6, to show you new features and features that are now possible.
- The future of .NET modern application development
- Deep dive into .NET 6: the new and upcoming
- .NET Team "Consulting Expert"
.NET 6 themes
We started planning for .NET 6 at the end of 2020. We identified eight themes in a wide range of themes, including industry scenarios, support, and education. These topics represent half to three quarters of our publishing work. There are many projects that have not risen to the level of themes, or are significant but not themes (for example, supports Apple Silicon device ).
The following are the topics of .NET 6 and each topic is summarized and described in one sentence. They are listed in the same order as shown themesof.net
- .NET is attractive to new developers and students --- Provides an intentionally simplified experience in the Visual Studio product, including clear documentation, simpler code models and fewer files and concepts, as well as deploying artifacts to An intuitive path to testing and production environments.
- .NET has an excellent client application development experience --- provides a cross-platform client application foundation that can seamlessly meet the needs of desktop, mobile and web developers, and is based on existing application types such as Blazor and Xamarin Build and expand.
- .NET is recognized as a compelling framework for building cloud-native applications ------provides basic cloud-native features mainly for performance and observability, and improves integration with cloud-native and containers ecosystem , And a cloud-native component ( yarp ), which showcases many of the value of .NET and key cloud use cases.
- Enterprise and LTS --- Provide simpler and more predictable models to combine .NET with mission-critical applications and better meet the needs of large enterprises and government customers.
- Develop the .NET ecosystem by improving quality, confidence and support ------Establish long-term community cooperation, aiming to elevate community developers to a level similar to Microsoft, and (on the other hand) provide new Features and experience make it easier for enterprise developers to rely on libraries in community open source projects, and community open source projects are not necessarily related to or supported by large companies.
- improves the inner loop performance of .NET developers ------Improves the work efficiency of developers, including improving build performance, hot restart and hot reload.
- uses runtime execution information (PGO) to improve startup and throughput --- provides a new model based on runtime information to improve performance, which can be used for faster startup, higher throughput and smaller binary files.
- meets the expectations of developers --- based on feedback in the entire .NET product to improve, and to enable new solutions with existing features.
The following post discusses some of these topics in more detail:
.NET platform unification
We have discussed a lot about unifying in past posts and conferences, but it is missing from the topic. The unification of the platform has been integrated into everything we do and does not need its own theme. One can think of it as a big topic beyond the topics listed. It runs through multiple themes and is the basic assumption for the team to move forward.
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 will consider these factors and provide a pragmatic and appropriate experience, and tend to have no observable experience differences. EventPipe project is another similar example.
Product confidence
We will soon begin to release an "live" version for production support. Our current goal is August. Our development model is oriented towards enabling production workloads, even though we are completing work on all the topics just mentioned.
Product confidence starts at dotnet.microsoft.com site. Starting from Preview 1, it ran half of the site load on .NET 6. Although it is not large in scale, it is a mission-critical site for our team and we attach great importance to it. .NET 6 has always worked for us like a champion.
We also work with the Microsoft team that deploys production applications on the .NET preview. They did this to take advantage of the new .NET features as early as possible. 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 effective and labor-saving methods. These teams provide us with early feedback and help us ensure that new features are ready for global production use. They also significantly influence the final feature shape because they are our first production users.
All of these early field tests with real applications make us believe that .NET 6 will be ready to run your application.
The rest of the article is dedicated to the new features in Preview 4.
Tools: Use Visual Studio debugger and dotnet CLI for hot reload
Hot reloading is a new experience that allows you to edit the source code of the application while it is running, without having to manually pause the application or hit breakpoints. Hot reload improves developer productivity by reducing the number of times required to restart a running application.
In this version, hot reloading is applicable to many types of applications, such as WPF, Windows Forms, WinUI, ASP.NET, console applications and other frameworks running on the CoreCLR runtime. We are also working hard to introduce this technology to WebAssembly, iOS and Android applications running on Mono, but this will still appear (in a preview later).
To start testing this feature, please install Visual Studio 2019 version 16.11 Preview 1 and use the Visual Studio debugger (F5) to launch your application. After the application is 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 image below.
Hot reload is also available through dotnet monitoring tool. Preview 4 contains multiple fixes that improve the experience.
If you want to know more about hot reload, you can read NET hot reload introduction .
System.Text.Json support for IAsyncEnumerable
IAsyncEnumerable<T> is an important feature added with .NET Core 3.0 and C# 8. The new enhancement supports the use of IAsyncEnumerable<T> objects for System.Text.Json (de)serialization.
The following example uses a stream as the representation of any asynchronous data source. The source can be a file on the local machine, or the result of a database query or Web service API call.
Stream serialization
System.Text.Json now supports serializing IAsyncEnumerable<T> values into JSON arrays, 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]}
The IAsyncEnumerable value only supports the use of asynchronous serialization methods. Attempts to serialize using synchronous methods will result in a NotSupportedException being thrown.
Stream deserialization
Streaming deserialization requires a new API that returns IAsyncEnumerable<T>. We added the JsonSerializer.DeserializeAsyncEnumerable method for this, 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);
}
This example will deserialize elements on demand and is very useful when working with particularly large data streams. It only supports reading from the root-level JSON array, although it can be relaxed based on feedback in the future.
The existing DeserializeAsync method nominally supports IAsyncEnumerable<T>, 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; }
}
In this example, the deserializer will buffer all 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 function
Writable JSON DOM function 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 when it is impossible or undesirable to use the POCO type, or when the JSON schema is not fixed and must be checked.
- Allows effective modification of a subset of large trees. For example, you can efficiently navigate to a subsection of a large JSON tree and read an array from that subsection or deserialize a POCO. LINQ can also be used with it.
- Allows the use of C# dynamic keywords, which allows the use of loosely typed, more script-like models.
We are looking for support dynamic feedback . If dynamic support is important to you, please give us your feedback.
More details are provided in dotnet/runtime #6098
Writable DOM API
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 {...};
}
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("[10,11,12]");
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":[10,11,12]}}
// Indexers for property names and array elements are supported and can be chained
Debug.Assert(jObject["MyChildObject"]["MyArray"][1].GetValue<int>() == 11);
Microsoft.Extensions.Logging compile-time source code generator
.NET 6 introduced the LoggerMessageAttribute type. This property is part of the Microsoft.Extensions.Logging namespace, and when used, it generates the performant log API. The source code generation logging support is designed to provide a highly available and high-performance logging solution for modern .NET applications. The automatically generated source code depends on the ILogger interface and LoggerMessage.Define function.
When LoggerMessageAttribute is used in some logging methods, the source generator will be triggered. When triggered, it can either automatically generate the implementation of the part of the method it is decorating, or generate compile-time diagnostics with hints for proper usage. Compile-time logging solutions are usually much faster at runtime than existing logging methods. It achieves this by minimizing boxing, temporary allocation, and copying.
Directly using LoggerMessage.Define API manually has the following advantages:
- Shorter and simpler syntax: use of declarative properties instead of code boilerplate.
- Guide the developer to experience: The generator gives a warning to help the developer do the right thing.
- Support any number of log parameters. LoggerMessage.Define supports up to six.
- Support dynamic log level. It is impossible to use LoggerMessage.Define alone.
- If you want to track improvements and known issues, please refer to dotnet/runtime\#52549 .
Basic usage
To use LoggerMessageAttribute, consumer classes and methods need to be partial.
The code generator is triggered at compile time and generates the implementation of some methods.
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);
}
In the previous example, the logging method is static, and the log level is specified in the attribute definition. When using this property in a static context, an ILogger instance is required as a parameter. You can also choose to use this attribute in a non-static context. For more examples and usage scenarios, please visit document compile-time log source generator.
System.Linq enhancements
new System.LINQ API requested and contributed by the community.
Enumerable support for index and range parameters
The Enumerable.ElementAt method now accepts the index of the end of the enumerable object, as shown in the following example.
Enumerable.Range(1, 10).ElementAt(\^2); // returns 9
Added Enumerable.Take overload that accepts a Range parameter. It simplifies the slicing of enumerable sequences:
- source.Take(..3) instead of source.Take(3)
- source.Take(3..) instead of source.Skip(3)
- source.Take(2..7) instead of source.Take(7).Skip(2)
- source.Take(^3..) instead of source.TakeLast(3)
- source.Take(..^3) instead of source.SkipLast(3)
- source.Take(^7..^3) instead of source.TakeLast(7).SkipLast(3).
Thanks \@dixin for their contribution to the implementation.
TryGetNonEnumeratedCount
The TryGetNonEnumeratedCount method attempts to get the source enumerable count without forcing enumeration. This method is useful in situations where it is useful to pre-allocate 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);
}
TryGetNonEnumeratedCount check the source of the implementation of ICollection/ICollection<T> or utilize some internal optimization adopted by Linq.
DistinctBy/UnionBy/IntersectBy/ExceptBy
New variants have been added to the set operation, allowing the use of key selector functions to specify equality, as shown in the example below.
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) }
MaxBy/MinBy
The MaxBy and MinBy methods allow the use of key selectors to find the largest or smallest element, 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)
Chunk
Chunk can be used to block an enumerable source 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} }
Thanks to Robert Andersson for his contribution to the implementation.
FirstOrDefault/LastOrDefault/SingleOrDefault overload uses default parameters
If the source enumeration is empty, the existing FirstOrDefault/LastOrDefault/SingleOrDefault methods return default(T). A new overload has been added, accepting the default parameters to be returned in this case, as shown in the following example.
Enumerable.Empty<int>().SingleOrDefault(-1); // returns -1
Thank you \@Foxtrek64 for your contribution to the implementation.
accepts three enumerated Zip overloads
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))
{
}
Thanks to Huo Yaoyuan for their contribution to the implementation.
Significantly improved FileStream performance on Windows
FileStream has been rewritten in .NET 6 for higher performance and reliability on Windows.
rewrite project has carried out five PRs in phases:
- Introduce FileStreamStrategy as the first step in FileStream rewriting
- FileStream rewrite the second part
- file stream optimization
- FileStream rewrite: use IValueTaskSource instead of TaskCompletionSource
- FileStream rewrite: Cache ValueTaskSource in
The end result is that FileStream will never block when created for asynchronous IO on Windows. This is a major improvement. You can observe this in the benchmark test, we will see soon.
Configuration
The first PR enables FileStream to choose an implementation at runtime. The most obvious benefit of this mode is that you can switch back to the old .NET 5 implementation, you can use
The following settings in runtimeconfig.json are implemented.
{
"configProperties": {
"System.IO.UseNet5CompatFileStream": true
}
}
Next, we plan to add a io_uring strategy , it takes advantage of recent kernel Linux functions of the same name.
Performance benchmark
Let's use BenchmarkDotNet to measure the 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++)
{
await fileStream.WriteAsync(_buffer);
}
}
[GlobalCleanup]
public void Cleanup() => File.Delete("file.txt");
}
``ini
BenchmarkDotNet=v0.13.0, OS=Windows 10.0.18363.1500 (1909/November2019Update/19H2)
Intel Xeon CPU E5-1650 v4 3.60GHz, 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 and SSD drives enable BitLocker
result:
- Reading 1 MB files is now 2 times faster, and writing speed is 4 times faster.
- Memory allocation dropped from 39 KB to 1 KB! This is an improvement of 97.5%!
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
improvements were made to the date and time related types: .
New DateOnly and TimeOnly structures
Added date and time only structure , with the following characteristics:
- Each represents half of a DateTime, or 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 working hours. It is consistent with the time type of SQL Server.
- Supplement the existing date/time types (DateTime, DateTimeOffset, TimeSpan, TimeZoneInfo).
- In the System namespace, it is provided in CoreLib, just like the existing related types.
Performance improvements to DateTime.UtcNow
This improvement has the following benefits:
- 2.5 times performance of getting the system time on Windows .
- Take advantage of the 5-minute sliding cache of Windows leap second data instead of fetching it every time it is called.
Supports Windows and IANA time zones on all platforms
This improvement has the following benefits:
- Implicit conversion when using TimeZoneInfo.FindSystemTimeZoneById ( https://github.com/dotnet/runtime/pull/49412 )
- Explicit conversion through the new API on TimeZoneInfo: TryConvertIanaIdToWindowsId, TryConvertWindowsIdToIanaId
And HasIanaId ( https://github.com/dotnet/runtime/issues/49407 ) - Improved cross-platform support and interoperability between systems using different time zone types.
- TimeZoneConverter OSS library is required to delete. This feature is now built-in.
Improved time zone display name
This improved has the following benefits:
- Disambiguate from the display names in the list returned by TimeZoneInfo.GetSystemTimeZones.
- Utilize ICU / CLDR to globalize data.
- Only applicable to Unix. Windows still uses registry data. This may change in the future.
other
- The display name and standard name of the UTC time zone are hard-coded to English and now use the same language as the rest of the time zone data (CurrentUICulture on Unix, the default language of the operating system on Windows).
- Due to size limitations, the time zone display name in WASM is changed to use the non-localized IANA ID.
- The TimeZoneInfo.AdjustmentRule nested class makes its BaseUtcOffsetDelta internal property public, and obtains a new constructor that takes baseUtcOffsetDelta as a parameter. ( https://github.com/dotnet/runtime/issues/50256
- TimeZoneInfo.AdjustmentRule also got other fixes for loading time zone on Unix ( https://github.com/dotnet/runtime/pull/49733), (https://github.com/dotnet/runtime/pull/50131)
CodeGen
The following improvements have been made to the RyuJIT compiler.
Community contribution
@SingleAccretion has been busy making the following improvements in the past few months. This is an .NET 6 Preview 3 . Thank you!
- dotnet/runtime #50373 --- If the tree is a CSE candidate, do not fold the double negation
- dotnet/runtime #50450 --- Handle the conversion done by the assistant and the folding overflow operation in the value numbering
- dotnet/runtime #50702 --- Delete the must-init requirement of GS Cookie
- dotnet/runtime #50703 --- Do not confuse fgDispBasicBlocks in fgMorphBlocks
Dynamic PGO
The following improvements have been made to support dynamic PGO .
- dotnet/runtime # --- Update JIT to use the new "LikelyClass" record seen from PGO data processed across generations
- dotnet/runtime #50213 --- Tolerate inconsistent edge contours better
- dotnet/runtime #50633 --- fixed the hybrid PGO/nonPGO compilation
- dotnet/runtime #50765 --- Modify fgExpandRunRarelyBlocks
- dotnet/runtime #51593 --- Modify inline scale calculation
JIT loop optimization
The following improvements have been made loop optimization
- dotnet/runtime #50982 --- Reverse the cycle in general
- dotnet/runtime #51757 --- Do not recalculate the preds list during cyclic cloning
LSRA
The following improvements have been made to the linear scan register allocation (LRSA)
- dotnet/runtime #51281 --- Improve LRSA statistics to include register selection heuristics
optimization
- dotnet/runtime #49930 --- Folding null checks for const strings at the value number level
- dotnet/runtime #50000 --- Fold null check for initialization static read-only fields of ref type
- dotnet/runtime #50112 --- Do not assign string literals among potential BBJ_THROW candidates
- dotnet/runtime #50644 --- Enable CSE for VectorX.Create
- dotnet/runtime #50806 --- If there is an unexpected block after it, give up the tail call
- dotnet/runtime #50832 --- Update Vector<T> to support nint and nuint
- dotnet/runtime #51409 --- generalize the branch around airflow optimization
.NET Diagnostics: EventPipe for Mono and improved EventPipe performance
EventPipe is a cross-platform mechanism of .NET for outputting events, performance data and counters. Starting with .NET 6, we have moved the 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 .NET diagnostic CLI tools! This change is also accompanied by a small reduction in CoreCLR:
We also made some changes to improve EventPipe throughput under load. In the first few preview releases, we made a series of changes to increase the throughput by 2.06 times that .NET 5 can achieve:
- Use the data collected by the EventPipeStress framework in dotnet/diagnostics. The writer application writes the event as quickly as possible within 60 seconds. Record the number of successful and discarded events.
For more information, see dotnet/runtime #45518 .
IL tailoring
Warnings are enabled by default
The tailoring warning tells you where tailoring may delete the code used at runtime. These warnings were previously disabled by default because the warnings were very noisy, mainly because the .NET platform did not participate in tailoring as a first-class solution.
We commented out most of the .NET libraries (runtime libraries, not ASP.NET Core or Windows Desktop Framework) so that they generate accurate tailoring warnings. Therefore, we think it is time to enable clipping warnings by default.
You can disable warnings by setting <SuppressTrimAnalysisWarnings> to true. For earlier versions, you can set the same property to false to see the trim warning.
Tailoring warnings bring predictability to the tailoring process and give developers power. We will continue to annotate more .NET libraries, including ASP.NET Core in subsequent versions. We hope that the community can also improve the tailoring ecosystem by commenting more code to ensure complete tailoring.
More information:
default tailored mode = link
The new default clipping mode in .NET 6 is link. Linking TrimMode can not only tailor unused assemblies, but also tailor unused members, thereby significantly saving costs.
In .NET 5, tailoring will try to find and delete unreferenced assemblies by default. This is more secure, but provides limited benefits. The tailoring warning is now enabled by default, and developers can be confident in the tailoring results.
As an example, let's take a look at this tailoring improvement by tailoring one of the .NET SDK tools.
I will use crossgen, that is ready to run the compiler . It can be tailored with only some tailoring warnings, and the crossgen team can solve these problems.
First of all, let's publish crossgen as a standalone application without tailoring. It is 80
MB (including the .NET runtime and all libraries).
Then we can try (now the old version). NET 5 default tailoring mode, copyused. The result dropped to 55 MB.
The new .NET 6 default crop mode link further reduces the individual file size to 36MB.
We hope that the new link tailoring model will better meet tailoring expectations: significant savings and predictable results.
Share model with Native AOT
We also Native AOT experiment , which should improve the Native AOT compilation experience in roughly the same way.
Single file release
The following improvements have been made to the single-file application release.
Static analysis
An analyzer for single-file publishing was added in .NET 5 to warn Assembly.Location
And some other APIs that behave differently in a single file package.
For .NET 6 Preview 4, we improved the analysis to allow custom warnings. If your API does not work in single-file publishing, you can now mark it with the [RequiresAssemblyFiles] attribute, and a warning will appear if the analyzer is enabled. Adding this attribute will also silence all warnings related to a single file in the method, so you can use that warning to propagate warnings up to your public API.
When PublishSingleFile is set to true, the analyzer is automatically enabled for exe projects, but you can also enable it for any project by setting EnableSingleFileAnalysis to true. This may help if you want to embed the library in a single file package.
compression
Single file packages now support compression, which can be enabled by setting the property EnableCompressionInSingleFile to true. At runtime, the files are decompressed into memory as needed. Compression can provide huge space savings for certain scenarios.
Let's take a look at the single file publishing with and without compression used NuGet Package Explorer
Uncompressed: 172 MB
After compression: 71.6 MB
Compression can significantly increase the startup time of an application, especially on Unix platforms (because they have a copy-free fast startup path that cannot be used with compression). You should test your application after enabling compression to see if the additional startup cost is acceptable.
PublishReadyToRun now uses crossgen2 by default
Crossgen2 is now enabled by default when publishing ReadyToRun images. It also optionally supports the generation of composite images.
Expose the following settings so that you can configure the release with the code ready to run. These settings are set to their default values.
PublishReadyToRun now uses crossgen2 by default
Crossgen2 is now enabled by default when publishing ReadyToRun images. It also optionally supports the generation of composite images.
Expose the following settings so that you can configure the release with the code ready to run. These settings are set to their default values.
CLI installation for .NET 6 SDK optional workloads
SDK workload that can be installed on the .NET SDK afterwards to support various 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 the preview 4 maui-check
Tool because it contains other components not yet available in Visual Studio or as a .NET SDK workload. To try the .NET SDK experience (using iOS as an example), please 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, please follow the installation instructions provided by the ASP.NET blog.
Preview 4 includes .NET MAUI workloads for iOS, Android, tvOS, MacOS, and MacCatalyst.
Please note that the dotnet workload installation will copy the workload from NuGet.org to your SDK installation, so if the SDK installation location is protected (meaning in the admin/root location), you need to run elevated/sudo.
Built-in SDK version check
To make it easier to track when the new version of the SDK and runtime are available, we have 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 in each feature band.
CLI template (dotnet new)
Preview 4 introduces a new template search function. dotnet new --search will be at NuGet.org
Search for matching templates. During the upcoming preview, the data used for this search will be updated more frequently.
The templates installed in the CLI can be used in the CLI and Visual Studio. The early problem that user-installed templates are lost when installing a new version of the SDK has been resolved, but the templates installed before .NET 6 Preview 4 need to be reinstalled.
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 the update is available through --update-check and --update-apply. This will now reflect template updates faster, support NuGet sources you define, and support --interactive authorization credentials.
In Preview 4 and the upcoming preview, the output of the dotnet new command will be cleaned up to focus on the information you need most. For example, dotnet new --install <package> only lists the templates that have just been installed, not all templates.
To support these and upcoming changes to dotnet new, we are making major changes to the template engine API, which may affect anyone hosting the template engine. These changes will appear in Preview 4 and Preview 5. If you host the template engine, please https://github.com/dotnet/templating so that we can work with you to avoid or minimize interruptions.
stand by
.NET 6 will be released in November 2021 and will provide three years of support Long Term Support (LTS) version platform matrix has been significantly expanded.
The new content is:
- Android
- IOS
- Mac and Mac Catalyst, suitable for x64 and Apple Silicon (aka "M1")
- Windows Arm64 (especially Windows desktop)
The .NET 6 Debian container image is based on Debian 11 ("bullseye"), is currently being tested .
the end
At this point we have entered the .NET 6 version. Although the final version in November seems to have a long way to go, we are close to completing feature development. Now is a good time for feedback, because the shape of the new feature has now been determined, and we are still in an active development phase, so it is easy to take action based on the feedback.
Speaking of November, please book some time to watch .NET Conf 2021 between November 9th and 11th. It will definitely be exciting and interesting. We will release the final .NET 6 version on November 9th, and a longer blog post than this one.
Still looking for more reading? You can check out our new dialogue series. There are many detailed insights on the new features of .NET 6. If you have any technical questions, please ask on Microsoft Q&A .
We hope you enjoy the trial preview version 4.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。