Aujourd'hui, nous annonçons .NET Core 3.0 Preview 6 . Il comprend des mises à jour pour la compilation d'assemblages pour un démarrage amélioré, l'optimisation des applications pour la taille avec des améliorations de l'éditeur de liens et EventPipe. Nous avons également publié de nouvelles images Docker pour Alpine sur ARM64.

Mise à jour WPF et Windows Forms
L'équipe WPF a maintenant terminé de publier la plupart de la base de code WPF sur GitHub . En fait, ils viennent de publier la source de quinze assemblées . Pour tous ceux qui connaissent WPF, les noms d'assembly doivent être très familiers.
Dans certains cas, les tests sont toujours dans l'arriéré pour être publiés au plus tard à 3.0 GA. Cela dit, la présence de tout ce code devrait permettre à la communauté WPF de participer pleinement à la modification de WPF. Il est évident à la lecture de certains des problèmes de GitHub que la communauté a son propre arriéré qu'elle attendait de réaliser. Thème sombre, peut-être?
Images de docker alpin
Les images Docker sont désormais disponibles pour .NET Core et ASP.NET Core sur ARM64. Ils n'étaient auparavant disponibles que pour x64.
Les images suivantes peuvent être utilisées dans un Dockerfile
ou avec un docker pull
, comme illustré ci-dessous:
docker pull mcr.microsoft.com/dotnet/core/runtime:3.0-alpine-arm64v8
docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine-arm64v8
Améliorations du canal d'événement
Event Pipe prend désormais en charge plusieurs sessions. Cela signifie que vous pouvez consommer des événements avec EventListener in-proc et avoir simultanément des clients de canal d'événements hors processus.
Nouveaux compteurs Perf ajoutés:
- % Temps en GC
- Taille de tas Gen 0
- Taille de tas de génération 1
- Taille de tas Gen 2
- Taille du tas LOH
- Taux d'allocation
- Nombre d'ensembles chargés
- Nombre de threads ThreadPool
- Surveiller le taux de conflit de verrouillage
- File d'attente des éléments de travail ThreadPool
- Taux d'éléments de travail terminés ThreadPool
L'attachement du profileur est désormais implémenté en utilisant la même infrastructure de canal d'événement.
Voir Jouer avec les compteurs de David Fowler pour avoir une idée de ce que vous pouvez faire avec le canal d'événement pour effectuer vos propres enquêtes de performances ou simplement surveiller l'état de l'application.
Voir dotnet-counters pour installer l'outil dotnet-counters.
Optimisez vos applications .NET Core avec des images ReadyToRun
Vous pouvez améliorer le temps de démarrage de votre application .NET Core en compilant vos assemblys d'application au format ReadyToRun (R2R). R2R est une forme de compilation anticipée (AOT).
Les binaires R2R améliorent les performances de démarrage en réduisant la quantité de travail que le JIT doit faire pendant le chargement de votre application. Les binaires contiennent un code natif similaire à ce que le JIT produirait, ce qui lui donne un peu de vacances lorsque les performances sont les plus importantes (au démarrage). Les binaires R2R sont plus volumineux car ils contiennent à la fois du code de langage intermédiaire (IL), qui est toujours nécessaire pour certains scénarios, et la version native du même code, pour améliorer le démarrage.
R2R est pris en charge avec .NET Core 3.0. Il ne peut pas être utilisé avec des versions antérieures de .NET Core.
Exemples de numéros de performances
Les numéros de performances suivants sont collectés à l'aide d'un exemple d'application WPF . L'application a été publiée comme autonome et n'a pas utilisé l'éditeur de liens d'assemblage (couvert plus loin dans ce post).
Application IL uniquement:
- Temps de démarrage: 1,9 secondes
- Utilisation de la mémoire: 69,1 Mo
- Taille de l'application: 150 Mo
Avec les images ReadyToRun:
- Temps de démarrage: 1,3 seconde.
- Utilisation de la mémoire: 55,7 Mo
- Taille de l'application: 156 Mo
Images ReadyToRun, expliquées
Vous pouvez R2R compiler les bibliothèques et les binaires d'application. À l'heure actuelle, les bibliothèques ne peuvent être compilées que R2R dans le cadre d'une application, et non pour être livrées en tant que package NuGet. Nous aimerions avoir plus de commentaires sur l'importance de ce scénario.
La compilation des assemblages AOT est disponible en tant que concept avec .NET depuis longtemps, remontant au .NET Framework et NGEN . NGEN présente un inconvénient majeur, à savoir que la compilation doit être effectuée sur les machines clientes, à l'aide de l'outil NGEN. Il n'est pas possible de générer des images NGEN dans le cadre de la création de votre application.
Entrez .NET Core. Il est livré avec crossgen , qui produit des images natives dans un format plus récent appelé ReadyToRun . Le nom décrit sa proposition de valeur principale, à savoir que ces images natives peuvent être construites dans le cadre de votre génération et sont «prêtes à fonctionner» sans aucun travail supplémentaire sur les machines clientes. C'est une amélioration majeure, et aussi une victoire importante pour le changement climatique.
En termes de compatibilité, les images ReadyToRun sont similaires aux assemblys IL, avec quelques différences clés.
- Les assemblys IL contiennent uniquement du code IL . Ils peuvent s'exécuter sur n'importe quel runtime qui prend en charge le cadre cible donné pour cet assembly. Par exemple, un assembly
netstandard2.0
peut s'exécuter sur .NET Framework 4.6+ et .NET Core 2.0+, sur n'importe quel système d'exploitation pris en charge (Windows, macOS, Linux) et architecture (Intel, ARM, 32 bits, 64 bits). - Les assemblys R2R contiennent IL et du code natif. Ils sont compilés pour une version d'exécution et un environnement d'exécution (RID) .NET Core minimum spécifiques. Par exemple, un assemblage
netstandard2.0
peut être compilé R2R pour .NET Core 3.0 et Linux x64. Il ne sera utilisable que dans cette configuration ou dans une configuration compatible (comme .NET Core 3.1 ou .NET Core 5.0, sous Linux x64), car il contient du code natif qui n'est utilisable que dans cet environnement d'exécution.
Instructions
La compilation ReadyToRun est une fonctionnalité opt-in de publication uniquement. Nous en avons publié une version d'aperçu avec .NET Core 3.0 Preview 5.
Pour activer la compilation ReadyToRun, vous devez:
- Définissez la propriété
PublishReadyToRun
sur true
. - Publiez à l'aide d'un
RuntimeIdentifier
explicite.
Remarque: Lorsque les assemblys d'application sont compilés, le code natif produit est spécifique à la plate-forme et à l'architecture (c'est pourquoi vous devez spécifier un RuntimeIdentifier valide lors de la publication).
Voici un exemple:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup> </Project>
Et publiez à l'aide de la commande suivante:
dotnet publish -r win-x64 -c Release
Remarque: Le RuntimeIdentifier
peut également être défini dans le fichier de projet.
Remarque: ReadyToRun n'est actuellement pris en charge que pour les applications autonomes . Il sera activé pour les applications dépendantes du framework dans un aperçu ultérieur.
La génération de symboles natifs peut être activée en définissant la propriété PublishReadyToRunEmitSymbols
sur true
dans votre projet. Vous n'avez pas besoin de générer de symboles natifs à des fins de débogage. Ces symboles ne sont utiles qu'à des fins de profilage.
Le SDK prend actuellement en charge un moyen d'exclure certains assemblys de la compilation en images ReadyToRun. Cela peut être utile dans les cas où certains assemblages n'ont pas vraiment besoin d'être optimisés pour les performances. Cela peut aider à réduire la taille de l'application. Cela pourrait également être une solution de contournement utile dans les cas où le compilateur ReadyToRun ne parvient pas à compiler un certain assembly. L'exclusion se fait à l'aide du groupe d'éléments PublishReadyToRunExclude. Exemple:
<ItemGroup> <PublishReadyToRunExclude Include="FilenameOfAssemblyToExclude.dll" /> </ItemGroup>
Compilations multi-plateformes / architectures
Le compilateur ReadyToRun ne prend actuellement pas en charge le ciblage croisé. Vous devez compiler sur une cible donnée. Par exemple, si vous souhaitez des images R2R pour Windows x64, vous devez exécuter la commande de publication sur cet environnement.
Exceptions à cela:
- Windows x64 peut être utilisé pour compiler des images Windows ARM32, ARM64 et x86.
- Windows x86 peut être utilisé pour compiler des images Windows ARM32.
- Linux x64 peut être utilisé pour compiler des images Linux ARM32 et ARM64.
Liaison d'assemblage
Le SDK .NET core 3.0 est fourni avec un outil qui peut réduire la taille des applications en analysant IL et en supprimant les assemblages inutilisés.
Avec .NET Core, il a toujours été possible de publier des applications autonomes qui incluent tout le nécessaire pour exécuter votre code, sans nécessiter l'installation de .NET sur la cible de déploiement. Dans certains cas, l'application ne nécessite qu'un petit sous-ensemble du cadre pour fonctionner et pourrait potentiellement être beaucoup plus petite en n'incluant que les bibliothèques utilisées.
Nous utilisons l' éditeur de liens IL pour analyser l'IL de votre application afin de détecter le code réellement requis, puis supprimer les bibliothèques de framework inutilisées. Cela peut réduire considérablement la taille de certaines applications. En règle générale, les petites applications de console de type outil bénéficient le plus, car elles ont tendance à utiliser des sous-ensembles assez petits du cadre et sont généralement plus adaptées au découpage.
Pour utiliser cet outil, définissez PublishTrimmed=true
dans votre projet et publiez une application autonome:
dotnet publish -r <rid> -c Release
La sortie de publication comprendra un sous-ensemble des bibliothèques de framework, selon ce que le code d'application appelle. Pour une application helloworld, l'éditeur de liens réduit la taille de ~ 68 Mo à ~ 28 Mo.
Les applications ou les frameworks (y compris ASP.NET Core et WPF) qui utilisent la réflexion ou les fonctionnalités dynamiques associées se cassent souvent lorsqu'ils sont coupés, car l'éditeur de liens ne connaît pas ce comportement dynamique et ne peut généralement pas déterminer quels types de frameworks seront nécessaires pour la réflexion. au moment de l'exécution. Pour couper de telles applications, vous devez indiquer à l'éditeur de liens tous les types nécessaires à la réflexion dans votre code et dans tous les packages ou frameworks dont vous dépendez. Assurez-vous de tester vos applications après le découpage.
Pour plus d'informations sur IL Linker, consultez la documentation ou visitez le référentiel mono / linker .
Remarque: Dans les versions précédentes de .NET Core, ILLink.Tasks était fourni en tant que package NuGet externe et offrait une grande partie des mêmes fonctionnalités. Il n'est plus pris en charge - veuillez mettre à jour le dernier SDK 3.0 et essayer la nouvelle expérience!
Utilisation de l'éditeur de liens et de ReadToRun ensemble
L'éditeur de liens et le compilateur ReadyToRun peuvent être utilisés pour la même application. En général, l'éditeur de liens réduit la taille de votre application, puis le compilateur prêt à fonctionner la rendra un peu plus grande, mais avec des gains de performances significatifs. Il vaut la peine de tester dans différentes configurations pour comprendre l'impact de chaque option.
Remarque: dotnet / sdk # 3257 empêche le lieur et ReadyToRun d'être utilisés ensemble pour les applications WPF et Windows Forms. Nous travaillons sur la correction de cela dans le cadre de la version .NET Core 3.0.
Exemple d'hébergement natif
L'équipe a récemment publié un exemple d'hébergement natif . Il illustre une approche de meilleures pratiques pour l'hébergement de .NET Core dans une application native.
Dans le cadre de .NET Core 3.0, nous exposons désormais des fonctionnalités générales aux hôtes natifs .NET Core qui n'étaient auparavant disponibles que pour les applications gérées .NET Core via les hôtes .NET Core officiellement fournis. La fonctionnalité est principalement liée au chargement de l'assemblage. Cette fonctionnalité devrait faciliter la production d'hôtes natifs pouvant tirer parti de l'ensemble des fonctionnalités de .NET Core.
Prise en charge HTTP / 2 dans HttpClient
HTTP / 2 est une révision majeure du protocole HTTP. Certaines des caractéristiques notables de HTTP / 2 sont la prise en charge de la compression d'en-tête et des flux entièrement multiplexés sur la même connexion. Bien que HTTP / 2 préserve la sémantique de HTTP (en-têtes HTTP, méthodes, etc.), il s'agit d'un changement par rapport à HTTP / 1.x dans la façon dont les données sont encadrées et envoyées via le câble.
HttpClient
ajoute désormais des supports pour effectuer des requêtes HTTP / 2. Bien que la valeur par défaut reste HTTP / 1.1, vous pouvez choisir d'utiliser HTTP / 2 en définissant la version sur votre message de demande HTTP.
var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };
Vous pouvez également envoyer par défaut des requêtes HTTP / 2 en définissant la propriété HttpClient
sur HttpClient
.
var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001"), DefaultRequestVersion = new Version(2, 0) };
En conséquence de ce changement de trame, les serveurs et les clients doivent négocier la version de protocole utilisée. ALPN (Application-Layer Protocol Negotiation) est une extension TLS qui permet au serveur et au client de négocier la version du protocole utilisée dans le cadre de leur négociation TLS. Bien qu'il soit possible d'avoir une connaissance préalable entre le serveur et le client sur le protocole, la plupart des serveurs ne prennent en charge ALPN que comme seul moyen d'établir une connexion HTTP / 2. En tant que tel, HTTP / 2 est négocié par HttpClient
uniquement sur une connexion TLS.
Dans les scénarios de développement lorsque le serveur et le client savent a priori que les deux parleront HTTP / 2 non chiffrés, vous pouvez établir une connexion HTTP / 2 sur du texte clair en définissant un commutateur AppContext
ou une variable d'environnement ( DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT=1
).
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
Clôture
Veuillez essayer les nouvelles fonctionnalités. Veuillez signaler les problèmes liés aux bogues ou à toute expérience difficile que vous rencontrez. Nous voulons la rétroaction! Vous pouvez également déposer des demandes de fonctionnalités, mais elles devront probablement attendre d'être mises en œuvre jusqu'à la prochaine version à ce stade.
Nous approchons maintenant de la fin de la fonctionnalité complète pour .NET Core 3.0, et nous faisons maintenant la transition de l'attention de l'équipe vers la qualité de la version. Nous avons quelques mois de correction de bogues et de travail sur les performances à venir. Nous apprécierons également vos commentaires tout au long de ce processus.
Sur cette note, nous allons bientôt basculer les branches principales des référentiels .NET Core vers la prochaine version majeure, probablement au moment ou peu après la version Preview 7 (juillet).
Merci d'avoir essayé les aperçus .NET Core 3.0. Nous apprécions votre aide. À ce stade, nous nous concentrons sur l'obtention d'une version finale entre vos mains.
Richard LanderPM, .NET Team