Ankündigung der .NET Core 3.0-Vorschau 6

Heute kündigen wir .NET Core 3.0 Preview 6 an . Es enthält Updates zum Kompilieren von Assemblys für einen verbesserten Start und zur Optimierung der Größe von Anwendungen mit Linker- und EventPipe-Verbesserungen. Wir haben auch neue Docker-Images für Alpine auf ARM64 veröffentlicht.





WPF- und Windows Forms-Update


Das WPF-Team hat nun die Veröffentlichung des größten Teils der WPF-Codebasis auf GitHub abgeschlossen . Tatsächlich haben sie gerade eine Quelle für fünfzehn Versammlungen veröffentlicht . Für alle, die mit WPF vertraut sind, sollten die Baugruppennamen sehr vertraut sein.


In einigen Fällen befinden sich noch Tests im Rückstand, um bei oder vor 3.0 GA veröffentlicht zu werden. Das Vorhandensein dieses gesamten Codes sollte es der WPF-Community jedoch ermöglichen, sich uneingeschränkt an Änderungen in WPF zu beteiligen. Aus dem Lesen einiger GitHub-Probleme geht hervor, dass die Community über einen eigenen Rückstand verfügt, auf dessen Realisierung sie gewartet hat. Dunkles Thema vielleicht?


Alpine Docker Bilder


Docker-Images sind jetzt sowohl für .NET Core als auch für ASP.NET Core auf ARM64 verfügbar. Sie waren bisher nur für x64 verfügbar.


Die folgenden Bilder können in einer Dockerfile oder mit docker pull , wie unten gezeigt:


  • docker pull mcr.microsoft.com/dotnet/core/runtime:3.0-alpine-arm64v8
  • docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine-arm64v8

Verbesserungen der Ereignisleitung


Event Pipe unterstützt jetzt mehrere Sitzungen. Dies bedeutet, dass Sie Ereignisse mit EventListener in-proc konsumieren und gleichzeitig nicht prozessbedingte Event-Pipe-Clients haben können.


Neue Perf Counters hinzugefügt:


  • % Zeit in GC
  • Gen 0 Heap Size
  • Gen 1 Heap Size
  • Gen 2 Heap Size
  • LOH Heap Size
  • Zuteilungsrate
  • Anzahl der geladenen Baugruppen
  • Anzahl der ThreadPool-Threads
  • Überwachungssperrkonfliktrate
  • ThreadPool Work Items Queue
  • ThreadPool-Rate abgeschlossener Arbeitselemente

Profiler Attach wird jetzt mit derselben Event Pipe-Infrastruktur implementiert.


Unter Spielen mit Zählern von David Fowler erhalten Sie eine Vorstellung davon, was Sie mit Event Pipe tun können, um Ihre eigenen Leistungsuntersuchungen durchzuführen oder einfach den Anwendungsstatus zu überwachen.


Informationen zum Installieren des Dotnet-Zählertools finden Sie unter Punktnetzzähler.


Optimieren Sie Ihre .NET Core-Apps mit ReadyToRun-Images


Sie können die Startzeit Ihrer .NET Core-Anwendung verbessern, indem Sie Ihre Anwendungsassemblys im ReadyToRun-Format (R2R) kompilieren. R2R ist eine Form der AOT-Kompilierung.


R2R-Binärdateien verbessern die Startleistung, indem sie den Arbeitsaufwand reduzieren, den die JIT beim Laden Ihrer Anwendung leisten muss. Die Binärdateien enthalten ähnlichen nativen Code wie die JIT, wodurch die JIT ein bisschen Urlaub bekommt, wenn die Leistung am wichtigsten ist (beim Start). R2R-Binärdateien sind größer, da sie sowohl IL-Code (Intermediate Language) enthalten, der für einige Szenarien noch benötigt wird, als auch die native Version desselben Codes, um den Start zu verbessern.


R2R wird mit .NET Core 3.0 unterstützt. Es kann nicht mit früheren Versionen von .NET Core verwendet werden.


Beispielleistungszahlen


Im Folgenden sind die Leistungszahlen aufgeführt, die mit einer Beispiel-WPF-Anwendung erfasst wurden. Die Anwendung wurde als eigenständig veröffentlicht und verwendete nicht den Assembly-Linker (der später in diesem Beitrag behandelt wird).


Nur-IL-Anwendung:


  • Startzeit: 1,9 Sekunden
  • Speichernutzung: 69,1 MB
  • Anwendungsgröße: 150 MB

Mit ReadyToRun-Bildern:


  • Startzeit: 1,3 Sekunden.
  • Speichernutzung: 55,7 MB
  • Anwendungsgröße: 156 MB

ReadyToRun-Bilder, erklärt


Sie können R2R sowohl Bibliotheken als auch Anwendungsbinärdateien kompilieren. Derzeit können Bibliotheken nur als Teil einer Anwendung R2R-kompiliert werden, nicht als NuGet-Paket. Wir möchten mehr Feedback darüber, ob dieses Szenario wichtig ist.


AOT-Kompilierungsassemblys sind seit langem als Konzept für .NET verfügbar und gehen auf .NET Framework und NGEN zurück . NGEN hat einen entscheidenden Nachteil: Die Kompilierung muss auf Client-Computern mit dem NGEN-Tool durchgeführt werden. Es ist nicht möglich, NGEN-Images als Teil Ihres Anwendungsbuilds zu generieren.


Geben Sie .NET Core ein. Es wird mit crossgen geliefert , das native Bilder in einem neueren Format namens ReadyToRun erzeugt . Der Name beschreibt sein primäres Wertversprechen: Diese nativen Images können als Teil Ihres Builds erstellt werden und sind ohne zusätzliche Arbeit auf Client-Computern "betriebsbereit". Das ist eine große Verbesserung und auch ein wichtiger Gewinn für den Klimawandel.


In Bezug auf die Kompatibilität ähneln ReadyToRun-Images IL-Assemblys mit einigen wesentlichen Unterschieden.


  • IL-Assemblys enthalten nur IL-Code . Sie können zu jeder Laufzeit ausgeführt werden, die das angegebene Zielframework für diese Assembly unterstützt. Beispielsweise kann eine netstandard2.0 Assembly unter .NET Framework 4.6+ und .NET Core 2.0+ unter jedem unterstützten Betriebssystem (Windows, macOS, Linux) und jeder Architektur (Intel, ARM, 32-Bit, 64-Bit) ausgeführt werden.
  • R2R-Assemblys enthalten IL und nativen Code. Sie werden für eine bestimmte minimale .NET Core-Laufzeitversion und Laufzeitumgebung (RID) kompiliert. Beispielsweise kann eine netstandard2.0 Assembly R2R für .NET Core 3.0 und Linux x64 kompiliert werden. Es kann nur in dieser oder einer kompatiblen Konfiguration (wie .NET Core 3.1 oder .NET Core 5.0 unter Linux x64) verwendet werden, da es nativen Code enthält, der nur in dieser Laufzeitumgebung verwendet werden kann.

Anleitung


Die ReadyToRun-Kompilierung ist eine reine Veröffentlichungsoption. Wir haben eine Vorschau-Version mit .NET Core 3.0 Preview 5 veröffentlicht.


Um die ReadyToRun-Kompilierung zu aktivieren, müssen Sie:


  • Setzen Sie die PublishReadyToRun Eigenschaft auf true .
  • Veröffentlichen Sie mit einem expliziten RuntimeIdentifier .

Hinweis: Wenn die Anwendungsassemblys kompiliert werden, ist der erzeugte native Code plattform- und architekturspezifisch (weshalb Sie beim Veröffentlichen einen gültigen RuntimeIdentifier angeben müssen).


Hier ist ein Beispiel:


 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup> </Project> 

Und veröffentlichen Sie mit dem folgenden Befehl:


 dotnet publish -r win-x64 -c Release 

Hinweis: Der RuntimeIdentifier kann auch in der Projektdatei festgelegt werden.


Hinweis: ReadyToRun wird derzeit nur für eigenständige Apps unterstützt . Es wird in einer späteren Vorschau für Framework-abhängige Apps aktiviert.


Die native Symbolgenerierung kann aktiviert werden, indem die PublishReadyToRunEmitSymbols Eigenschaft in Ihrem Projekt auf true . Sie müssen keine nativen Symbole für Debugging-Zwecke generieren. Diese Symbole sind nur für Profilierungszwecke nützlich.


Das SDK unterstützt derzeit eine Möglichkeit, bestimmte Assemblys von der Kompilierung in ReadyToRun-Images auszuschließen. Dies kann in Fällen nützlich sein, in denen bestimmte Baugruppen nicht wirklich für die Leistung optimiert werden müssen. Dies kann dazu beitragen, die Größe der Anwendung zu reduzieren. Dies kann auch eine nützliche Problemumgehung für Fälle sein, in denen der ReadyToRun-Compiler eine bestimmte Assembly nicht kompilieren kann. Der Ausschluss erfolgt über die Elementgruppe PublishReadyToRunExclude. Beispiel:


 <ItemGroup> <PublishReadyToRunExclude Include="FilenameOfAssemblyToExclude.dll" /> </ItemGroup> 

Plattformübergreifende / architektonische Zusammenstellungen


Der ReadyToRun-Compiler unterstützt derzeit kein Cross-Targeting. Sie müssen auf einem bestimmten Ziel kompilieren. Wenn Sie beispielsweise R2R-Images für Windows x64 möchten, müssen Sie den Veröffentlichungsbefehl in dieser Umgebung ausführen.


Ausnahmen hiervon:


  • Windows x64 kann zum Kompilieren von Windows ARM32-, ARM64- und x86-Images verwendet werden.
  • Windows x86 kann zum Kompilieren von Windows ARM32-Images verwendet werden.
  • Linux x64 kann zum Kompilieren von Linux ARM32- und ARM64-Images verwendet werden.

Baugruppenverknüpfung


Das .NET Core 3.0 SDK enthält ein Tool, mit dem Sie die Größe von Apps reduzieren können, indem Sie IL analysieren und nicht verwendete Assemblys kürzen.


Mit .NET Core war es immer möglich, eigenständige Apps zu veröffentlichen, die alles enthalten, was zum Ausführen Ihres Codes erforderlich ist, ohne dass .NET auf dem Bereitstellungsziel installiert werden muss. In einigen Fällen benötigt die App nur eine kleine Teilmenge des Frameworks, um zu funktionieren, und kann möglicherweise erheblich verkleinert werden, indem nur die verwendeten Bibliotheken einbezogen werden.


Wir verwenden den IL-Linker , um die IL Ihrer Anwendung zu scannen, um festzustellen, welcher Code tatsächlich benötigt wird, und um dann nicht verwendete Framework-Bibliotheken zu kürzen. Dies kann die Größe einiger Apps erheblich reduzieren. In der Regel profitieren kleine werkzeugähnliche Konsolen-Apps am meisten, da sie in der Regel relativ kleine Teilmengen des Frameworks verwenden und sich normalerweise besser zuschneiden lassen.


Um dieses Tool zu verwenden, setzen Sie PublishTrimmed=true in Ihrem Projekt und veröffentlichen Sie eine eigenständige App:


 dotnet publish -r <rid> -c Release 

Die Veröffentlichungsausgabe enthält eine Teilmenge der Framework-Bibliotheken, je nachdem, was der Anwendungscode aufruft. Bei einer Helloworld-App reduziert der Linker die Größe von ~ 68 MB auf ~ 28 MB.


Anwendungen oder Frameworks (einschließlich ASP.NET Core und WPF), die Reflektion oder verwandte dynamische Funktionen verwenden, werden beim Trimmen häufig unterbrochen, da der Linker dieses dynamische Verhalten nicht kennt und normalerweise nicht bestimmen kann, welche Framework-Typen für die Reflektion erforderlich sind zur Laufzeit. Um solche Apps zu kürzen, müssen Sie dem Linker alle Typen mitteilen, die durch Reflektion in Ihrem Code und in allen Paketen oder Frameworks, von denen Sie abhängig sind, benötigt werden. Testen Sie Ihre Apps nach dem Zuschneiden.


Weitere Informationen zum IL Linker finden Sie in der Dokumentation oder im Mono / Linker Repo.


Hinweis: In früheren Versionen von .NET Core wurde ILLink.Tasks als externes NuGet-Paket ausgeliefert und bot weitgehend die gleiche Funktionalität. Es wird nicht mehr unterstützt - bitte aktualisieren Sie auf das neueste 3.0 SDK und probieren Sie die neue Erfahrung aus!


Linker und ReadToRun zusammen verwenden


Der Linker und der ReadyToRun-Compiler können für dieselbe Anwendung verwendet werden. Im Allgemeinen verkleinert der Linker Ihre Anwendung, und der sofort einsatzbereite Compiler macht sie wieder etwas größer, jedoch mit einem erheblichen Leistungsgewinn. Es lohnt sich, in verschiedenen Konfigurationen zu testen, um die Auswirkungen der einzelnen Optionen zu verstehen.


Hinweis: dotnet / sdk # 3257 verhindert, dass der Linker und ReadyToRun zusammen für WPF- und Windows Forms-Anwendungen verwendet werden. Wir arbeiten daran, dies im Rahmen der .NET Core 3.0-Version zu beheben.


Native Hosting-Beispiel


Das Team hat kürzlich ein Native Hosting-Beispiel veröffentlicht . Es zeigt einen Best-Practice-Ansatz für das Hosten von .NET Core in einer nativen Anwendung.


Als Teil von .NET Core 3.0 stellen wir nun allgemeine Funktionen für native .NET Core-Hosts bereit, die zuvor nur für von .NET Core verwaltete Anwendungen über die offiziell bereitgestellten .NET Core-Hosts verfügbar waren. Die Funktionalität bezieht sich hauptsächlich auf das Laden von Baugruppen. Diese Funktionalität sollte es einfacher machen, native Hosts zu erstellen, die alle Funktionen von .NET Core nutzen können.


HTTP / 2-Unterstützung in HttpClient


HTTP / 2 ist eine wichtige Überarbeitung des HTTP-Protokolls. Einige der bemerkenswerten Funktionen von HTTP / 2 sind die Unterstützung der Header-Komprimierung und vollständig gemultiplexter Streams über dieselbe Verbindung. Während HTTP / 2 die Semantik von HTTP (HTTP-Header, -Methoden usw.) beibehält, ist es eine Änderung von HTTP / 1.x, wie Daten gerahmt und über das Kabel gesendet werden.


HttpClient jetzt Unterstützung für HTTP / 2-Anforderungen. Während die Standardeinstellung HTTP / 1.1 bleibt, können Sie sich für die Verwendung von HTTP / 2 entscheiden, indem Sie die Version in Ihrer HTTP-Anforderungsnachricht festlegen.


 var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") }; // HTTP/1.1 request using (var response = await client.GetAsync("/")) { Console.WriteLine(response.Content); } // HTTP/2 request using (var request = new HttpRequestMessage(HttpMethod.Get, "/") { Version = new Version(2, 0) }) using (var response = await client.SendAsync(request)) { Console.WriteLine(response.Content); } 

Alternativ können Sie standardmäßig HTTP / 2-Anforderungen senden, indem Sie die DefaultRequestVersion Eigenschaft in HttpClient DefaultRequestVersion .


 var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001"), DefaultRequestVersion = new Version(2, 0) }; // Defaults to HTTP/2 using (var response = await client.GetAsync("/")) { Console.WriteLine(response.Content); } 

Infolge dieser Änderung des Framings müssen Server und Clients die verwendete Protokollversion aushandeln. Application-Layer Protocol Negotiation (ALPN) ist eine TLS-Erweiterung, mit der Server und Client die Protokollversion aushandeln können, die im Rahmen ihres TLS-Handshakes verwendet wird. Während es möglich ist, Vorkenntnisse zwischen dem Server und dem Client über das Protokoll zu haben, unterstützen die meisten Server nur ALPN als einzige Möglichkeit, eine HTTP / 2-Verbindung herzustellen. Daher wird HTTP / 2 von HttpClient nur über eine TLS-Verbindung ausgehandelt.


In Entwicklungsszenarien, in denen Server und Client von vornherein wissen, dass beide unverschlüsselt HTTP / 2 sprechen, können Sie eine HTTP / 2-Verbindung über Klartext herstellen, indem Sie einen AppContext Schalter oder eine Umgebungsvariable ( DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1 ) DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1 .


 AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); 

Schließen


Bitte probieren Sie die neuen Funktionen aus. Bitte reichen Sie Probleme für die Fehler oder herausfordernden Erfahrungen ein, die Sie finden. Wir wollen das Feedback! Sie können auch Feature-Anfragen einreichen, aber diese müssen wahrscheinlich warten, bis sie bis zur nächsten Version implementiert werden.


Wir stehen kurz vor der Fertigstellung der Funktionen für .NET Core 3.0 und verlagern den Fokus des Teams jetzt auf die Qualität der Version. Wir haben ein paar Monate Zeit, um Fehler zu beheben und die Leistung zu verbessern. Wir freuen uns über Ihr Feedback, wenn wir diesen Prozess ebenfalls durcharbeiten.


In diesem Sinne werden wir bald die Hauptzweige von .NET Core-Repos auf die nächste Hauptversion umstellen, wahrscheinlich bei oder kurz nach der Preview 7-Version (Juli).


Vielen Dank, dass Sie die Vorschau von .NET Core 3.0 ausprobiert haben. Wir bedanken uns für Ihre Hilfe. An diesem Punkt konzentrieren wir uns darauf, eine endgültige Veröffentlichung in Ihre Hände zu bekommen.




Richard Lander
PM, .NET-Team

Source: https://habr.com/ru/post/de456224/


All Articles