.NET Core 2.1 is finally here, and it has a lot of new and exciting features that showcase the impressive effort Microsoft has put into developing this newest version. Today, I'll present an overview of the most exciting features and explain how each can enhance your .NET Core projects.

Long-Term Support

.NET Core 2.1 supports a broad range of different operating systems, and it's also made notable improvements in managing platform versions. Because of this, it's shipping as a long-term support (LTS) release, which means that Microsoft will guarantee 3 years of support for this version.

.NET Core Tools
What is it?

It is Microsoft's attempt to get a good deployment and extensibility model for .NET tools, much like NPM global tools does. Up until now, any extensibility tool was only available per project by using DotnetCliToolReference.

All tools will be managed by the "dotnet tool" command succeeded by its available options. For now, tools can be installed in two modes only:

Global - copied to your user profile location (can be invoked directly from anywhere)

Ad-hoc - copied to a location of your choosing (must be invoked via full path if not added to PATH)

Some of the previously existing tools have been already incorporated into the SDK, most notably the file watcher (dotnet watch) and entity framework (dotnet ef). Project references to those tools need to be removed when upgrading from previous .NET Core versions.

How can tools help you?

Although this feature is clearly a work in progress and currently offers a very limited number of tools, having a way to manage the tools and having a common repository for them means that more and more tools will be developed. A list of all currently available tools is maintained here. dotnet-sonarscanner (Sonar analysis), dotnet-serve (HTTP server) and dotnet-sshdeploy (useful for SSH deploy) are some of the highlights.

Span<T> family
What is it?

The Span<T> and other related framework types were implemented in C# 7.2. They were intended to provide an allocation-free representation of memory to work with all different types/classes in the language and to help boost performance. 

Span<T> is a ref-like struct that represents contiguous regions of arbitrary memory, regardless of what is associated with that memory, which enables parsing and other computation without allocating.

Because of its characteristics, it can only live on the stack. This limits where it can be used and referenced, which creates an opening for the use of the other new Memory<T> that can satisfy those scenarios and be used mainly for async operations.

A complete description of how it works may be found here.

How can it help you?

This framework is primarily used for memory-efficient and high-performance computing with .NET, but it could easily turn into day-to-day code.

To use a very simple example, you could implicitly cast a byte array into a Span<T> and modify it like so: 

var bytes = new byte[100];
Span<byte> byteSpan = bytes;
byteSpan[1] = 42;

But what is really great about Span<T> is that it allows you to safely and efficiently handle subsets of arrays, data on the stack, pointers and even cast span types.

It's also important to note that a lot of methods overloads have been added all across .NET to support the Span<T> family. As an example, look at the string conversion below: 

var input = "15,36";
var separator = input.IndexOf(',');
var first = int.Parse(input.Substring(0, separator));
var second = int.Parse(input.Substring(separator + 1));

 This could be turned into an allocation-free implementation: 

var input = "15,36";
ReadOnlySpan<char> inputSpan = input.AsReadOnlySpan();
var separator = input.IndexOf(',');
int first = int.Parse(inputSpan.Slice(0, separator));
int second = int.Parse(inputSpan.Slice(separator + 1));
New SocketsHttpHandler
What is it?

With the help of the above-mentioned Span<T>, Microsoft built a new http message handler from the ground up to form the basis of higher-level networking APIs and to provide a faster and more consistent socket implementation through System.Net.Http.SocketsHttpHandler.

It is based on .NET sockets eliminating platform dependencies for better consistency, as well as simplified deployment and servicing. It also uses Span<T> as its base, giving it a significant performance improvement.

How can it help you?

This is now the default implementation in http pipelines starting with .NET Core 2.1, and it is recommended for use with any new or upgrading project. If you want to use the older implementation, you must explicitly set it by using AppContext.SetSwitch.

Windows Compatibility Pack
What is it?

Windows Compatibility Pack is a NuGet package that provides access to a vast number of APIs targeted for the .NET Framework.

How can it help you?

Windows Compatibility Pack helps port existing .NET Framework applications to .NET Core.

Not all the APIs are available, and some of them are Windows-only, so they need to be well analysed before migration occurs.

The porting process can be better structured by following these tips:

Runtime Performance Improvements

Microsoft has put a lot of effort into improving runtime performance as well. The Span<T> family is again very central to these improvements, as it's now used everywhere in core libraries.

An extensive explanation of everything that has been changed in .NET Core 2.1 may be found here.  Some of the most important improvements we can list include:

  • JIT - Improvements in devirtualization, as it can better recognize potential methods that can be called inline, most notably benefitting EqualityComparer<T>.Default. 

Threading - Reduced the overhead for calling thread static fields and hot paths. The CancellationTokens implementation was changed to focus more on reducing allocation and improving throughput than on scalability. There's also been an allocation reduction in general for async calls.

Formatting and parsing - As expected, primitive types have benefited a lot from Span<T> in this area by reducing memory allocation and improving throughput.

Other Features

Besides the features mentioned above, there are some others that are worth exploring. For instance, .NET Core 2.1 offers the ability to publish self-contained applications, which is a great build performance improvement for large projects. It also offers a number of new and enhanced cryptography APIs, tiered compilation for adaptive optimization and the consolidation of docker images into https://hub.docker.com/r/microsoft/dotnet/.

Conclusion

As we can see, there are a lot of new and exciting features in .NET Core 2.1, making this version another promising step forward for Microsoft in this cross-platform, scalable world. It's important to remember that brand new versions for ASP.NET Core (SignalR, https by default, updated templates and more) and Entity Framework (lazy loading!) are also available now to work on top of Core bases. If you're starting a new project, updating an older .NET Core or even maybe in need of porting a .NET framework, I highly recommend giving .NET Core 2.1 a try.

 

 


Author

Elton Silva

Elton is a .NET Developer at Avenue Code. He is passionate about all .NET technologies and how Microsoft is able to adapt to the latest technologies. And, also, he's passionate about always trying to follow as many sports as possible at the same time.