ASP.NET Core .NET 8 Preview 2: New Features and Updates

ASP.NET Core .NET 8 Preview 2: New Features and Updates
March 22, 2023
6 minutes read

In this article, we will explore the new features and improvements that are part of the second preview of ASP.NET Core in .NET 8.

We will cover the new Blazor QuickGrid component, improved Blazor WebAssembly performance with the jiterpreter, new analyzers for minimal APIs, new APIs in ProblemDetails to support more resilient integrations, improvements to ObjectPool with the new IResettable interface, and performance improvements to the named pipes transport.

Blazor QuickGrid component

The Blazor QuickGrid component is now part of .NET 8! QuickGrid is a high performance grid component for displaying data in tabular form. QuickGrid is built to be a simple and convenient way to display your data, while still providing powerful features like sorting, filtering, paging, and virtualization.

To get started with QuickGrid:

  • Add reference to the Microsoft.AspNetCore.Components.QuickGrid package.luaCopy

Loading code snippet...

  • Add the following Razor code to render a very simple grid

Loading code snippet...

You can see various examples of QuickGrid in action on the QuickGrid demo site.

QuickGrid was originally introduced as an experimental package based on .NET 7. As part of bringing QuickGrid into .NET 8 we’ve made some changes and improvements to the API. To update an existing Blazor app that uses QuickGrid to the .NET 8 version, you may need to make the following adjustments:

  • Rename the Value attribute on the Paginator component to State
  • Rename the IsDefaultSort attribute on columns to InitialSortDirection and add IsDefaultSortColumn=true to indicate the column should still be sorted by default.
  • Remove the ResizableColumns attribute on QuickGrid. Built-in support for resizable columns was removed.

Improved Blazor WebAssembly performance with the jiterpreter

The jiterpreter is a new runtime feature in .NET 8 that enables partial JIT support in the .NET IL interpreter to achieve improved runtime performance.

Blazor WebAssembly apps are able to run .NET code in the browser thanks to a small .NET runtime implemented in WebAssembly that gets downloaded with the app. This runtime is a .NET IL interpreter that is fully functional, reasonably small in size, and allows for fast developer iteration, but lacks the runtime performance benefits of native code execution through just-in-time (JIT) compilation. JITing to WebAssembly requires creating new WebAssembly modules on the fly and instantiating them, which poses unique challenges for the runtime. Blazor WebAssembly apps can instead choose to compile ahead-of-time (AOT) to WebAssembly to improve runtime performance but at the expense of a much larger download size. Since some common .NET coding patterns are incompatible with AOT, the .NET IL interpreter is still needed as a fallback mechanism to maintain full functionality.

The jiterpreter optimizes execution of interpreter bytecodes by replacing them with tiny blobs of WebAssembly code. By leveraging the interpreter as a baseline, we’re able to optimize the most important parts of the app without having to handle more complex or obscure cases and without overly complicating the runtime. While the jiterpreter isn’t a full JIT implementation, it significantly improves runtime performance without the size and build time overhead of AOT. The jiterpreter helps when using AOT too by optimizing cases where the runtime has to fallback to the interpreter.

In .NET 8 Preview 2, the jiterpreter is automatically enabled for your Blazor WebAssembly apps. You don’t have to do anything extra to turn it on.

The jiterpreter can significantly speed up the performance of low-level operations. For example, the following micro benchmark test for Span<byte>.Reverse() and String.Normalize() ran 46.7% and 86.9% faster respectively:

bytehide.com

These improvements add up and translate into better performance for higher layer features. In our JSON serialization tests, the jiterpreter is 40.8% faster:

bytehide.com

New analyzer to detect multiple

In .NET 8 Preview 2, a new analyzer has been added to detect when more than one parameter is being resolved from the body in a minimal API. The analyzer helps developers avoid errors and warns when multiple [FromBody] attributes are applied to parameters of a handler method.

For example, the following code will trigger the new analyzer warning:

Loading code snippet...

To address the analyzer warning, limit each handler to only one parameter resolved from the body, as shown in the following code:

Loading code snippet...

The new analyzer is an addition to the analyzers added in Preview 1 for API development and helps improve the development experience for developers working with minimal APIs.

New APIs in

In .NET 7, the ProblemDetailsService was introduced to improve the experience for generating error responses that comply with the ProblemDetails specification. In .NET 8 Preview 2, a new API called TryWriteAsync has been added to the IProblemDetailsService interface to make it easier for implementers to implement fallback behavior if the ProblemDetailsService was not able to generate a ProblemDetail.

Here is an example of how to use the new TryWriteAsync API in user middleware:

Loading code snippet...

New IResettable interface in ObjectPool

Microsoft.Extensions.ObjectPool provides support for pooling object instances in memory, which is especially useful when working with expensive to allocate or initialize objects.

In .NET 8 Preview 2, ObjectPool is becoming even easier to use thanks to the addition of the IResettable interface. This interface defines a method called TryReset() which can be used to reset an object back to its default state, making it available for reuse.

Here’s an example of how to use IResettable in conjunction with ObjectPool:

Loading code snippet...

In the above code, ReusableBuffer is an example of a type that can be reset to a default state, allowing it to be reused. With IResettable, bufferPool.Return(buffer) will automatically reset Data to its default state between uses.

Performance improvements to named pipes transport

In .NET 8 Preview 1, support for using named pipes with Kestrel was announced. In Preview 2, the performance of named pipe connections has been improved. Kestrel’s named pipe transport can now accept connections in parallel and reuse NamedPipeServerStream instances.

The time it takes to create 100,000 connections has significantly improved with the latest changes:

  • Before: 5.916 seconds
  • After: 2.374 seconds

These improvements were suggested by the community, and thanks go to the folks at Unity for contributing to this area.

You May Also Like

Optional Parameters in C#: What You Need to Know

Optional Parameters in C#: What You Need to Know

Programming in C# often requires flexibility and simplicity ...

What is Lock Keyword in C#? Main Usages

What is Lock Keyword in C#? Main Usages

IndexUnderstanding the C# Lock Keyword Can’t tell a lock fro...

Enumerate in C#: Detailed Explanation

Enumerate in C#: Detailed Explanation

Desperate to decode the mystery that is enumeration in C#? I...

Creating a JSON Class in C#: Detailed Guide

Creating a JSON Class in C#: Detailed Guide

In the world of application development, manipulation of dat...

Static Class in C#: How to Use It?

Static Class in C#: How to Use It?

Hello there, future C# aficionado! It’s time to roll down th...

DateTime Formatting in C#: Dev Guide

DateTime Formatting in C#: Dev Guide

Have you ever gotten frustrated handling dates and times in ...

Leave a reply

Loading comment form...