© ESB Basic/Shutterstock.com
.NET 5.0 Previews 1 bis 7

Viele kleine Schritte bis .NET 5.0


Wir werfen einen Blick auf .NET 5.0, das Microsoft für November 2020 angekündigt hat. Die ersten sieben Vorschauversionen fallen zwar im Vergleich zu den großen Ankündigungen, die es im Vorfeld gab, eher enttäuschend aus – aber dennoch wird .NET 5.0 viele attraktive Detailverbesserungen bringen. Sehen wir sie uns einmal genauer an.

Auf der Build-Konferenz im Mai 2019 hatte Microsoft .NET 5.0 für Ende 2020 als die Zusammenführung von .NET Framework, .NET Core und Mono/Xamarin zu einer einheitlichen Plattform für alle Anwendungsarten und alle Betriebssysteme mit einer einheitlichen Klassenbibliothek („One BCL“) und einem einheitlichen Werkzeugkasten („One SDK“) angekündigt. Lediglich zwei Runtimes („Core Runtime“ und „Mono Runtime“) sollten bleiben, aber aus Sicht des Anwendungsentwicklers gleich agieren.

Pandemiebedingt kommt „One .NET“ erst 2021

Seit der diesjährigen Build 2020 ist offiziell, dass Microsoft wesentliche Teile der Vereinheitlichung pandemiebedingt auf .NET 6.0 im November 2021 verschoben hat. .NET 5.0 erscheint im November 2020 mit weniger Innovationen als geplant.

Zu den gestrichenen Funktionen gehört auch die von vielen Entwicklern ersehnte Ahead-of-Time-Kompilierung (AOT) in Verbindung mit Tree Shaking (Aussortieren nicht verwendeter Codezeilen) für alle .NET-Anwendungsarten als schlankere und performantere Alternative zum bisherigen Just-in-Time-Compiler. „We will continue evolving the native AOT as an experimental project“, heißt es mittlerweile auf GitHub [1]. Für Blazor WebAssembly war AOT auch nach der Build 2020 noch auf der Roadmap in .NET 5.0 (Abb. 1), wurde aber am 5. Juni 2020 selbst dafür gestrichen. Dabei könnte gerade Blazor WebAssembly erheblich von AOT mit Tree Shaking profitieren, denn die Anwendungsgröße ist in der ersten veröffentlichten Version 3.2 vom Mai 2020 zu groß für öffentliche Internetanwendungen, die auch bei langsamem Netz schnell laden müssen, und auch nach dem Start kann die Ausführungsgeschwindigkeit nicht mit JavaScript-basierten Web-Frameworks mithalten. Microsoft selbst sieht das ein: „Blazor WebAssembly isn’t going to win in any performance comparisons with JavaScript based frameworks like Angular or React.“ [2] Technisch gesehen werden .NET 5.0 und 6.0 die Nachfolger von .NET Core 3.1 (Abb. 2). Was bisher nicht aus dem klassischen .NET Framework portiert wurde (z. B. ASP.NET Web Forms, WCF Server, Windows Workflow), wird auch nicht mehr portiert werden.

schwichtenberg_dotnet5_ausblick_1.tif_fmt1.jpgAbb. 1: Zusammengestrichene Blazor-Roadmap für .NET 5.0, Stand 27.7.2020 [3]
schwichtenberg_dotnet5_ausblick_2.tif_fmt1.jpgAbb. 2: Die Vereinheitlichung aller .NET-Varianten kommt nun erst mit .NET 6.0

Was bringt also .NET 5.0?

Nach so viel Enttäuschung, was .NET 5.0 alles nicht bringt, wird dieser Beitrag nun erörtern, was die bisherigen sieben Vorschauversionen von .NET 5.0 an Neuerungen bringen und was noch für die weiteren Vorabversionen (Preview 8, Release Candidate 1 und 2) geplant ist – bis zum Erscheinen von .NET 5.0 am 10. November 2020 im Rahmen der virtuellen .NET Conf 2020 [4].

Viele Leistungsverbesserungen

Ein großes Thema in .NET 5.0 ist erneut die Leistungsverbesserung. Microsoft hatte in .NET Core 1.0 bis 3.1 schon an der Performance von Laufzeitumgebung und Klassenbibliothek gearbeitet und ist weiterhin sehr um Optimierungen bemüht. Zwei Blogeinträge [5], [6] listen zahlreiche Leistungsverbesserungen in .NET 5.0 gegenüber .NET Core 3.1 auf. Das betrifft nicht nur den Just-in-Time-Compiler (insbesondere die in .NET 3.0 eingeführte Tiered Compilation) und den Garbage Collector, sondern auch viele Basisklassen, z. B. Zeichenkettenoperationen und reguläre Ausdrücke, Objektmengen, LINQ, Netzwerkprotokolle und die asynchrone Ausführung. Die Tabellen 1 und 2 zeigen exemplarisch die Leistungssteigerungen von .NET Framework 4.8 bis .NET 5.0.

Auch einige neue Methoden und Parameter wurden zur Leistungssteigerung ergänzt (z. B. MailAddress.TryCreate() und Task.WhenAny(Task, Task) als schnellere Alternative zu Task.WhenAny(params Task[]) für den häufigen Praxisfall von zwei Tasks. Dazu gehört auch ein HttpClient.Send() als Alternative zu HttpClient.SendAsync() für Fälle, in denen eine asynchrone Ausführung der HTTP-Anfrage nicht möglich ist und ein Warten auf eine asynchrone Antwort nur unnötigen Overhead bedeutet.

Method

Runtime

Mean

Ratio

Allocated

Uri.Ctor

.NET FW 4.8

443.2 ns

1.00

225 B

Uri.Ctor

.NET Core 3.1

192.3 ns

0.43

72 B

Uri.Ctor

.NET 5.0

129.9 ns

0.29

56 B

Tabelle 1: Verbesserungen beim Konstruktor der Klasse System.Uri

Method

Runtime

Mean

Ratio

OrderBy

.NET FW 4.8

100.78 us

1.00

OrderBy

.NET Core 3.1

101.03 us

1.00

OrderBy

.NET 5.0

85.46 us

0.85

Tabelle 2: Verbesserungen bei OrderBy() in LINQ-to-Objects

Bei der in .NET Core 3.0 eingeführten JIT-Strategie Tiered Compilation übersetzt der Just-in-Time-Compiler RyuJIT die Intermediate Language (IL) zunächst sehr schnell in Machinencode und optimiert erst später nur für die häufig verwendeten Methoden. Die für die Optimierungsentscheidung notwendige Zählung der Methodenaufrufe hat Microsoft in .NET 5.0 beschleunigt. Für Methoden mit Schleifen kann man die Umgebungsvariablen COMPlus_TC_OnStackReplacement und COMPlus_TC_QuickJitForLoops zur Steuerung der Tiered Compilation setzen. Beide Umgebungsvariablennamen verweisen tatsächlich auch in .NET 5.0 noch auf COMPlus, den Vorgängernamen des klassischen .NET Frameworks.

Der Garbage Collector verbessert u. a. den Umgang mit sogenannten angehefteten Objekten (Pinned Objects), die man in C# mit dem Schlüsselwort fixed erstellt, was nur in unsafe-Programmcodeblöcken erlaubt ist. Solche Pinned Objects darf der Garbage Collector nicht in andere Speicherbereiche verschieben. Für die Pinned Objects führt Microsoft in .NET 5.0 eine separate Behandlung bei der Speicherverwaltung ein, indem sie nun in einem eigenen Hauptspeicherbereich POH (Pinned Objects Heap) verwaltet werden. Die bisherigen Generationen-Heaps (0 bis 2) müssen damit keine Sonderbehandlung für die Pinned Objects mehr durchführen. Bisher schon gab es im Garbage Collector einen eigenen Heap für große .NET-Objekte (Large Object Heap, LOH). Neu im Garbage Collector ist auch, dass der Entwickler sich eine Datenstruktur mit Informationen über den letzten Lauf liefern lassen kann:

GCMemoryInfo gcInfo = GC.GetGCMemoryInfo();

Die Größe von .NET 5.0 in Docker-Containern wurde gegenüber .NET Core 3.1 verringert [7]. Zudem hat Microsoft in die Laufzeitumgebung die einfache Diagnosemöglichkeit für das Laden von Assemblies integriert, die es im klassischen .NET Framework gab und die bisher in .NET Core fehlte. In .NET 5.0 kommt dafür das Werkzeug dotnet-trace zum Einsatz [8].

.NET-5.0-Plattformen

Bei den unterstützten Betriebssystemen ist in .NET 5.0 Windows auf ARM64-Prozessoren neu hinzugekommen. Im Gegensatz zu anderen Neuerungen in .NET 5.0 will Microsoft die Windows-ARM64-Unterstützung auch auf .NET Core 3.1 zurückportieren. Für die Festlegung des Ziel-Frameworks verwendet Microsoft im .NET SDK seit .NET Core sogenannte Target Framework Moniker (TFM). Für .NET 5.0 will Microsoft ein neues Konzept [9] umsetze...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang