Marginale Neuerungen in .NET 9.0 Release Candidate 1

.NET 9.0 biegt mit dem ersten Release Candidate auf die Zielgerade ein. Gegenüber der letzten Preview 7 gibt es nur marginale API-Verbesserungen.

In Pocket speichern vorlesen Druckansicht

(Bild: Pincasso/Shutterstock.com)

Lesezeit: 6 Min.
Von
  • Dr. Holger Schwichtenberg
Inhaltsverzeichnis

Nach sieben Preview-Versionen hat Microsoft .NET 9.0 Release Candidate 1 veröffentlicht. .NET beherrscht die Komprimierung mit zlib und Brotli schon seit Jahren. Mit .NET 9.0 führt Microsoft nun zwei Klassen ZLibCompressionOptions und BrotliCompressionOptions ein, mit denen sich spezifische Kompressionseinstellungen vornehmen lassen. Bei der Klasse ZLibCompressionOptions gibt es die Eigenschaften CompressionStrategy (eine Enumeration) und CompressionLevel (eine Ganzzahl 0 bis 9), wobei 0 keine Komprimierung bedeutet. Bei der Klasse BrotliCompressionOptions gibt es nur eine Eigenschaft Quality (Ganzzahl 0 bis 11).

Das Listing 1 zeigt ein Einsatzbeispiel, das für alle zehn zlib-Komprimierungslevel sowie für alle zwölf Quality-Level bei der Brotli-Komprimierung die Größe eines komprimierten Textes mit 100.000 Zeichen ausgibt. Abbildung 1 zeigt die Ausgabe des Listings.

 // Erzeuge einen Text mit 100000 zufälligen Zeichen
 string text = new string(Enumerable.Range(0, 100000).Select(i => (char)(65 + i % 26)).ToArray());
 Console.WriteLine("Originaltext: " + text.Length);
 
 for (int i = 0; i <= 9; i++)
 {
  // Kopiere den Text in einen MemoryStream
  var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(text));
  var compressedStream = new MemoryStream();
  using var zipStream = new ZLibStream(compressedStream, new ZLibCompressionOptions() { CompressionLevel = i, CompressionStrategy = ZLibCompressionStrategy.Default });
  uncompressedStream.CopyTo(zipStream);
  zipStream.Flush();
 
  Console.WriteLine($"Länge bei ZLib-Komprimierungslevel #{i}: " + compressedStream.Length);
 }
 
 for (int i = 0; i <= 11; i++)
 {
  // Kopiere den Text in einen MemoryStream
  var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(text));
  var compressedStream = new MemoryStream();
  using var brotliStream = new BrotliStream(compressedStream, new BrotliCompressionOptions() { Quality = i });
  uncompressedStream.CopyTo(brotliStream);
  brotliStream.Flush();
 
  Console.WriteLine($"Länge bei Brotli-Komprimierungslevel #{i}: " + compressedStream.Length);
 }

Listing 1: Einsatz der ZLibCompressionOptions und BrotliCompressionOptions

Ausgabe von Listing 1 (Abb. 1).

(Bild: Dr. Holger Schwichtenberg)

Bei der Klasse TarEntry bietet .NET 9.0 nun die neue Eigenschaft DataOffset, die Entwicklerinnen und Entwicklern das Auslesen der Positionen des ersten Bytes eines Eintrags im TAR-Archiv-Stream erlaubt. Das könnte laut Microsoft nützlich sein für Parallelzugriffe auf große TAR-Dateien.

In .NET MAUI 9.0 bietet das Steuerelement Microsoft.Maui.Controls.Label nun neben den Ausrichtungen linksbündig (HorizontalTextAlignment="Start"), rechtsbündig (HorizontalTextAlignment="End") und zentriert (HorizontalTextAlignment="Center") endlich auch Blocksatz (HorizontalTextAlignment="Justify"), siehe Listing 2 und Abbildung 2.

<Label 
  Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis nulla eu felis fringilla vulputate. Nullam porta eleifend lacinia. Donec at iaculis tellus."
  HorizontalTextAlignment="Justify"/>

Listing 2: Blocksatz mithilfe von Microsoft.Maui.Controls.Label

Textformatierungsmöglichkeiten im Label-Steuerelement in .NET MAUI 9.0 (Abb. 2).

(Bild: Dr. Holger Schwichtenberg)

In Blazor können Entwicklerinnen und Entwickler nun beim Steuerelement <InputNumber> das HTML-Attribut type setzen, zum Beispiel

<h5>ohne type</h5>
<InputNumber min="1" max="10" step="1" @bind-Value="Zahl" />
<h5>type="range"</h5>
<InputNumber type="range" min="1" max="10" step="1" @bind-Value="Zahl" />
<h5>type="text"</h5>
<InputNumber type="text" min="1" max="10" step="1" @bind-Value="Zahl" />

In .NET 8.0 hatte Microsoft Schlüssel bei der Dependency Injection eingeführt, mit denen Entwicklerinnen und Entwickler mehrere Instanzen einer Klasse im Dependency-Injection-Container mit verschiedenen Schlüsseln registrieren können. In ASP.NET Core 9.0 können nun auch Middleware-Klassen geschlüsselte Dienste im Konstruktor und den Methoden Invoke() und InvokeAsync() konsumieren.

Bei WebSockets-Verbindungen ließ sich bisher schon per Eigenschaft KeepAliveInterval (sowohl im Client als auch im Server) festlegen, wie häufig zur Gegenseite eine Ping-Nachricht gesendet werden soll. Es gab aber bisher keine Konsequenz, wenn die Gegenseite nicht antwortete. Nun kann man per KeepAliveTimeout den Abbruch der Verbindung erzwingen, wenn die Gegenseite nicht innerhalb einer bestimmten Zeit antwortet. Im Server konfiguriert man beispielsweise alle zehn Sekunden eine kurze Nachricht und bricht die Verbindung ab, wenn der Server nicht binnen zwei Sekunden antwortet:

app.UseWebSockets(
    new WebSocketOptions { 
        KeepAliveInterval = TimeSpan.FromSeconds(10), 
        KeepAliveTimeout = TimeSpan.FromSeconds(2)
        });

Im Client sieht die Konfiguration der Eigenschaft KeepAliveTimeout so aus:

var httpClient = new HttpClient();
var uri = new Uri("wss://server:1234/ws"); // wss: für SSL!
var cancellationToken = new CancellationTokenSource().Token;
using var client = new ClientWebSocket();
client.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
client.Options.KeepAliveInterval = TimeSpan.FromSeconds(15);
client.Options.KeepAliveTimeout = TimeSpan.FromSeconds(1); // neu in .NET 9
await client.ConnectAsync(uri, httpClient, cancellationToken);
CUI.Yellow("Verbunden mit WebSockets Server");

Der schon bekannte .NET-SDK-Kommandozeilenbefehl

dotnet dev-certs https --trust

mit dem Entwicklerinnen und Entwickler einem von ASP.NET Core selbst generierten Entwicklungszertifikat vertrauen können, funktioniert nun nicht mehr nur wie bisher auf Windows und macOS, sondern auch unter Ubuntu und Fedora Linux mit Chrome und Firefox.

Der neue .NET-SDK-Befehl

dotnet workload history

zeigt den zeitlichen Ablauf der Veränderungen der SDK-Workload-Installationen auf einem Entwicklungssystem an.

Wie schon bei den Vorschauversionen Preview 6 und Preview 7 gibt es keinerlei Release Notes vom Entity-Framework-Core-Entwicklungsteam. Auch das Dokument "What's New in EF Core 9" hat sich seit dem 11. Juni 2024 nicht mehr verändert. Man findet aber auf GitHub 45 geschlossene Issues im Milestone "9.0.0-rc1", darunter folgende Punkte:

  • Neben UseSqlServer() kann man in der Methode OnConfiguring() in der Kontextklasse nun auch UseAzureSql() oder UseAzureSynapse() für die Verbindung zu den Cloud-Varianten von SQL Server aufrufen. Microsoft will damit spezielle Features der Cloud-Varianten wie den eigenen Datentyp JSON ausnutzen können. Es ist allerdings nicht dokumentiert, welche Features der Cloud-Varianten Microsoft konkret nutzt. In einem Schnelltest zeigten sich aber fehlende Features: UseNetTopologySuite() und UseHierarchyId() kompilieren nicht zusammen mit UseAzureSql().
  • Microsoft hat das von Entity Framework Core 9.0 im Standard angenommene Kompatibilitätslevel für Microsoft SQL Server nach längerer Diskussion auf 150 heruntergesetzt, was einem Microsoft SQL Server 2019 entspricht. In Entity Framework Core 8.0 war das Level 160 (SQL Server 2022). Entwicklerinnen und Entwickler sollten das Kompatibilitätslevel explizit mit UseCompatibilityLevel() setzen, wenn sie mit anderen SQL-Server-Versionen als dem Standard arbeiten.
  • Microsoft unterstützt seit Entity Framework Core 8.0 Mengen von primitiven Typen (etwa int[], List<Guid>), aber nicht das Mapping verschachtelter Mengen, etwa int[][]. Das bleibt auch in Entity Framework Core 9.0 so, die Fehlermeldung ist nun aber konkreter: "int[][] is a primitive collection of a primitive collection. Nested primitive collections are not yet supported with relational database providers.". Zuvor hieß es nur allgemeiner: "is not a supported primitive type or a valid entity type".

.NET 9.0 Release Candidate 1 installiert man im Rahmen von Visual Studio 2022 Version 17.12 Preview 2 oder eigenständig mit dem Setup-Paket von der Website. Einige neue Einträge gibt es in der Liste der Breaking Changes in .NET 9.0 gegenüber .NET 8.0.

Microsoft hat den 12. November 2024 als Erscheinungstermin für .NET 9.0 offiziell bekannt gegeben. Bis dahin wird es im Oktober noch den Release Candidate 2 geben. Die stabile Version präsentieren Heise, iX und der dpunkt.verlag zusammen mit www.IT-Visions.de bei dem Online-Event betterCode() .NET 9.0 eine Woche später, am 19. November 2024.

(mai)