Il n’y a pas vraiment de surprise à proprement parlé puisque ces évolutions sont annoncées depuis un moment, mais les voir arriver, pouvoir les télécharger et les tester cela fait une différence de taille ! D’autant que nous parlons ici d’avancées majeures bouleversant un peu le monde .NET et C# autant que celui des IoT
Une annonce énorme !
L’annonce est en effet de taille, pas seulement de façon imagée par l’impact des nouveautés, mais même par la taille du post sur Blog.Net de Microsoft, un véritable roman !
Il faut dire que le nombre des annonces est impressionnant autant que leurs implications.
C’est pourquoi j’ai décidé aujourd’hui de vous livrer une traduction de cette annonce in extenso, je reviendrai bien évidemment sur de nombreux points, voire tous, dans de prochains billets. Le temps de télécharger et de tester moi aussi. Tous les billets Dot.Blog se basent sur mon expérience et mon expertise, et comment être honnête si je publie une analyse sur des produits que je n’ai pas eu le temps d’utiliser ? C’est pourquoi je ne le ferai pas. Mais les annonces sont si importantes que je ne peux pas non plus les passer sous silence. D’où le choix de traduire le texte de l’annonce originale. Je n’ai pas encore testé tout cela, mais vous ne serez pas privé d’une information essentielle.
Attention : étant donnée la taille du texte et le mélange image / texte / extraits de code, j’ai utilisé Google Traduction pour ne pas y passer la journée. Mais rien que pour rendre l’ensemble lisible cela m’a pris plus d’une heure et demi et c’est loin d’être parfait. Mais je pense avoir un bon compromis entre traduction parfaite et rapidité de mise en ligne de ces informations cruciales. Merci de votre indulgence par avance ! Je reviendrai de toute façon plus en détail sous le format habituel dans les semaines et mois à venir tant il y a de choses à expérimenter !
Si vous préférez lire l’intégralité de ce texte dans sa version originale en langue cowboy cliquez ici !
L’annonce
Voici l’annonce du 10 novembre dans son intégralité, avec tous ses liens. Comme vous allez le voir tout est important, tout est essentiel, tout aura un impact sur nos productions, impossible donc de trier le bon grain de l’ivraie pour vous proposer un résumé car il n’y a rien à jeter ici ! Le post ici traduit émane de Richard Lander, Program Manager dans l’équipe .NET, donc quelqu’un de très bien placé pour parler de tout cela. Publié le 10/11/2020 donc, voici le texte :
Annonce de .NET 5.0
Richard
Nous sommes ravis de publier .NET 5.0 aujourd'hui et
que vous commenciez à l'utiliser. Il s'agit d'une version
majeure - y compris C
# 9 et F
# 5 -
avec un large éventail de nouvelles fonctionnalités et d'améliorations
convaincantes. Il
est déjà utilisé activement par les équipes de Microsoft et d'autres
entreprises, en production et pour les tests de
performances. Ces
équipes nous montrent d'excellents résultats qui démontrent des gains de
performances et / ou des opportunités de réduire les coûts d'hébergement de
leurs applications Web. Nous
exploitons notre
propre site Web sur la version 5.0 depuis l'aperçu
1. D'après ce que nous
avons vu et entendu jusqu'à présent, .NET 5.0 offre une valeur significative
sans trop d'efforts de mise à niveau. C'est
un excellent choix pour votre prochaine application et une mise à niveau simple
à partir des versions antérieures de .NET
Core. Nous espérons que vous apprécierez de l'utiliser sur
votre ordinateur de bureau, votre ordinateur portable et vos instances
cloud.
ASP.NET Core , EF
Core , C
# 9 et F
# 5 sont
également publiés aujourd'hui. .NET
Conf 2020 -
notre conférence
gratuite et virtuelle -
se tient aujourd'hui afin que vous puissiez en savoir plus sur toutes les
nouvelles versions.
Vous
pouvez télécharger
.NET 5.0 ,
pour Windows, macOS et Linux, pour x86, x64, Arm32,
Arm64.
Pour les utilisateurs de Visual Studio, vous avez
besoin de Visual
Studio 16.8 ou
version ultérieure pour utiliser .NET 5.0 sur Windows et la dernière version
de Visual
Studio pour Mac) sur
macOS. L' extension
C # pour Visual
Studio Code prend
déjà en charge .NET 5.0 et C # 9.
.NET 5.0 est la première version de notre voyage
d'unification .NET. Nous avons créé .NET
5.0 pour permettre à un groupe beaucoup plus important de développeurs de migrer
leur code et leurs applications .NET Framework vers .NET
5.0. Nous
avons également effectué une grande partie des premiers travaux de la version
5.0 afin que les développeurs Xamarin puissent utiliser la plate-forme unifiée
.NET lorsque nous publierons .NET 6.0. Il
y en a plus sur l'unification .NET, plus loin dans
l'article.
Le moment est venu de souligner l'incroyable
collaboration avec tous ceux qui contribuent au projet
.NET. Cette version marque la
cinquième version majeure de .NET en tant que projet open
source. Il
y a maintenant un grand mélange d'individus et de petites et grandes entreprises
(y compris les sponsors
de la Fondation .NET )
qui travaillent ensemble en tant que grande communauté sur divers aspects de
.NET dans l' organisation dotnet sur
GitHub . Les améliorations
apportées à .NET 5.0 sont le résultat de nombreuses personnes, de leurs efforts,
de leurs idées intelligentes, de leur attention et de leur amour pour la
plate-forme, tout cela au-delà de la gestion du projet par
Microsoft. De
la part de l'équipe principale travaillant quotidiennement sur .NET,
nous remercions tous ceux qui ont contribué à .NET
5.0 (et aux versions précédentes)!
Nous
avons introduit
.NET 5.0 en
mai 2019 et même défini la date de sortie de novembre 2020 à ce
moment-là. D'après
ce post: «nous expédierons .NET Core 3.0 en septembre, .NET 5 en novembre 2020,
puis nous avons l'intention de livrer une version majeure de .NET une fois par
an, chaque novembre». On
pourrait penser que «novembre 2020» était un chèque en blanc compte tenu de tous les défis de cette année, cependant, .NET 5.0 a été publié à
temps. Merci
à tous les membres de l'équipe qui ont rendu cela
possible! Je
sais que cela n'a pas été facile. Pour l'avenir, vous devriez vous attendre à .NET 6.0
en novembre 2021. Nous avons l'intention de publier de nouvelles versions de
.NET chaque novembre.
Le reste du blog est dédié à la mise en évidence et
au détail de la plupart des améliorations de .NET
5.0. Il y a aussi une mise à jour sur notre vision
d'unification .NET.
Points forts de .NET 5.0
Il existe de
nombreuses améliorations
importantes dans .NET 5.0 :
J'ai écrit de nombreux exemples pour les articles de
prévisualisation .NET 5.0. Vous voudrez peut-être
jeter un œil aux exemples
.NET 5.0 pour
en savoir plus sur les nouvelles fonctionnalités de C # 9 et des
bibliothèques.
.NET 5.0 a
une matrice
de prise en charge de plate-forme presque
identique à .NET
Core 3.1 ,
pour Windows, macOS et Linux. Si
vous utilisez .NET Core 3.1 sur un système d'exploitation pris en charge, vous
devriez pouvoir adopter .NET 5.0 sur cette même version du système
d'exploitation pour la plupart. L'ajout le plus important pour .NET 5.0 est Windows
Arm64.
.NET 5.0 est
une version
actuelle . Cela signifie qu'il
sera pris en charge pendant trois mois après la sortie de .NET
6.0. Par conséquent, nous prévoyons de prendre en charge
.NET 5.0 jusqu'à la mi-février 2022. .NET 6.0 sera une version LTS et sera pris
en charge pendant trois ans, tout comme .NET Core 3.1.
L'année dernière, nous avons partagé
une vision
d'une pile et d'un écosystème .NET unifiés . L'intérêt pour vous est
que vous pourrez utiliser un seul ensemble d'API, de langages et d'outils pour
cibler un large éventail de types d'applications, y compris les mobiles, le
cloud, les ordinateurs de bureau et l'IoT. Vous
réalisez peut-être que vous pouvez déjà cibler un large éventail de
plates-formes avec .NET aujourd'hui, cependant, les outils et les API ne sont
pas toujours les mêmes sur le Web et le mobile, par exemple, ou publiés en même
temps.
Dans le cadre de .NET 5.0 et 6.0, nous unissons .NET
en une seule expérience produit, tout en vous permettant de sélectionner
uniquement les parties de la plate-forme .NET que vous souhaitez
utiliser. Si vous souhaitez
cibler Mobile et non WebAssembly, vous n'avez pas besoin de télécharger les
outils WebAssembly, et vice versa. Idem
avec ASP.NET Core et WPF. Vous
aurez également un moyen beaucoup plus simple d'acquérir tous les outils .NET et
les packs de compilation et d'exécution dont vous avez besoin à partir de la
ligne de commande. Nous
activons une expérience de gestionnaire de packages (y compris l'utilisation de
gestionnaires de packages existants) pour les composants de la plate-forme
.NET. Ce
sera formidable pour de nombreux
scénarios. La construction rapide d'un environnement de
développement et CI / CD seront probablement les plus grands
bénéficiaires.
Nous avions l'intention de livrer l'intégralité de la
vision d'unification avec .NET 5.0, mais à la suite de la pandémie mondiale,
nous avons dû nous adapter aux besoins changeants de nos
clients. Nous avons travaillé
avec des équipes d'entreprises du monde entier qui avaient besoin d'aide pour
accélérer leur adoption des technologies cloud. Eux aussi ont dû
s'adapter aux besoins changeants de leurs
clients. En conséquence, nous livrons la vision à travers deux
versions.
La première étape vers cette vision a été
la consolidation
des dépôts .NET ,
y compris un grand sous-ensemble de Mono. Avoir
un référentiel pour le runtime et les bibliothèques pour .NET est une condition
préalable à la livraison du même produit partout. Il aide également à
apporter des modifications importantes qui affectent le temps d'exécution et les
bibliothèques, là où il y avait auparavant des limites de
dépôt. Certaines
personnes craignaient qu'un gros repo ne soit plus difficile à
gérer. Cela ne s'est pas avéré être le
cas.
Dans la version .NET 5.0, Blazor est le meilleur
exemple d'utilisation de la consolidation des dépôts et de l'unification
.NET. Le runtime et les
bibliothèques de Blazor
WebAssembly sont
désormais créés à partir
du référentiel
dotnet / runtime consolidé . Cela signifie que
Blazor WebAssembly et Blazor sur le serveur utilisent exactement le même code
pour ,
par exemple. Ce
n'était pas le cas pour Blazor avant .NET
5.0. L'approche que nous avons adoptée pour Blazor
WebAssembly est très similaire à ce que nous ferons avec Xamarin dans .NET
6.0.List<T>
Le .NET Framework reste un produit Microsoft pris en
charge et continuera à être pris en charge avec chaque nouvelle version de
Windows. Nous avons annoncé
l'année dernière que nous avions cessé
d'ajouter de nouvelles fonctionnalités à .NET Framework et que nous
avions terminé
d'ajouter des API .NET Framework à .NET Core . Cela signifie que le
moment est venu d'envisager de déplacer vos applications .NET Framework vers
.NET Core. Pour
les développeurs de clients .NET Framework, Windows Forms et WPF sont pris en
charge avec .NET 5.0. Nous
avons entendu de nombreux développeurs dire que le portage à partir de .NET
Framework est simple. Pour
les développeurs de serveurs .NET Framework, vous devez adopter ASP.NET Core
pour utiliser .NET 5.0. Pour
les développeurs Web Forms, nous pensons que Blazoroffre
une expérience de développeur similaire avec une implémentation efficace et
beaucoup plus moderne. Les
utilisateurs du serveur WCF et du flux de travail peuvent
rechercher des
projets de communauté qui prennent
en charge ces
frameworks . Le portage
de .NET Framework vers .NET Core doc
est un bon point de départ. Cela dit, garder votre application sur .NET Framework
est une bonne approche si vous êtes satisfait de votre
expérience.
L'équipe Windows travaille
sur Project Reunion en tant
que prochaine étape pour UWP et les technologies
associées. Nous
collaborons avec l'équipe de la Réunion pour nous assurer que .NET 5.0 et les
versions ultérieures fonctionneront bien avec WinUI et
WebView2. Le repo Project Reunion est le meilleur endroit pour
se tenir au courant des progrès.
Passons aux nouveautés de la version
5.0.
Langages
C # 9 et F
# 5 font
partie de la version .NET 5.0 et sont inclus dans le SDK .NET
5.0. Visual
Basic est également inclus dans le SDK
5.0. Il n'inclut pas les modifications de langue, mais a
des améliorations pour prendre en charge le Visual Basic Application Framework
sur .NET Core.
Les générateurs de source C
# sont
une nouvelle fonctionnalité importante du compilateur C
#. Ils
ne font pas techniquement partie de C # 9 car il n'a pas de syntaxe de
langage. Consultez Nouveaux
exemples de générateur de source C # pour
vous aider à utiliser cette nouvelle
fonctionnalité. Nous
prévoyons d'utiliser davantage les générateurs de sources dans le
produit .NET dans .NET 6.0 et
au-delà.
Afin d'essayer la nouvelle version nous-mêmes,
quelques-uns d'entre nous ont décidé de mettre à jour
le repo dotnet
/ iot pour
utiliser la nouvelle syntaxe C # 9 et cibler .NET
5.0. Les
changements ont entraîné la suppression de plus de 2 000 lignes de code,
simplement en adoptant une nouvelle syntaxe. Il utilise des
programmes, des enregistrements, des modèles et des expressions de commutation
de niveau supérieur. Il
a également été mis à jour pour tirer parti de l'ensemble complet d'annotations
Nullable dans les bibliothèques .NET. Nous
avons également mis à jour la documentation .NET
IoT . Nous
allons examiner quelques exemples de ce dépôt pour explorer C #
9.
Programmes de haut niveau
Le
programme led-blink est un bel exemple de programme
compact de premier niveau.
using System;
using System.Device.Gpio;
using System.Threading;
var pin = 18;
var lightTime = 1000;
var dimTime = 200;
Console.WriteLine($"Let's blink an LED!");
using GpioController controller = new ();
controller.OpenPin(pin, PinMode.Output);
Console.WriteLine($"GPIO pin enabled for use: {pin}");
// turn LED on and off
while (true)
{
Console.WriteLine($"Light for {lightTime}ms");
controller.Write(pin, PinValue.High);
Thread.Sleep(lightTime);
Console.WriteLine($"Dim for {dimTime}ms");
controller.Write(pin, PinValue.Low);
Thread.Sleep(dimTime);
}
Vous pouvez également voir l'utilisation de type
cible new
,
avec l'affectation à la controllern
variable. Le GpioController
type
n'est défini que sur le côté gauche de
l'affectation. Le
type est déduit du côté droit. Cette nouvelle syntaxe est une alternative
à var
,
dont le type ne s'affiche que sur le côté droit de l'affectation et est déduit
du côté gauche avec var
.
Les programmes de niveau supérieur peuvent également
gagner en complexité, en définissant des méthodes et en tirant parti des types
définis dans le même fichier ou dans d'autres
fichiers. L' exemple CharacterLcd illustre certaines de ces
fonctionnalités.
Modèles logiques et de
propriété
C # 9 inclut la prise en charge de nouveaux
modèles. Vous pouvez voir un
exemple de modèle logique dans le code
suivant du capteur
de gaz CCS811 .
var threshChoice = Console.ReadKey();
Console.WriteLine();
if (threshChoice.KeyChar is 'Y' or 'y')
{
TestThresholdAndInterrupt(ccs811);
}
Un autre nouveau modèle est celui des
propriétés. Vous
pouvez voir plusieurs vérifications de propriétés dans mon
exemple Mycroft
information access 6.0 . Le code
suivant est
extrait de l' exemple
de lecteur RFID et NFC PN532 .
if ( pollingType is null or { Length: > 15 }) { return null ; }
Ce code teste si pollingType
est nul ou contient plus que 15
octets.
Je veux vous montrer deux autres
modèles. Le premier est
un modèle
logique dans
le bus
CAN Mcp25xxx .
public static byte GetRxBufferNumber(Address address) => address switch
{
>= Address.RxB0D0 and <= Address.RxB0D7 => 0,
>= Address.RxB1D0 and <= Address.RxB1D7 => 1,
_ => throw new ArgumentException(nameof(address), $"Invalid address value {address}."),
};
Le second est
un modèle
logique dans Piezo
Buzzer Controller .
if (element is not NoteElement noteElement)
{
// In case it's a pause element we have only just wait desired time.
Thread.Sleep(durationInMilliseconds);
}
else
{
// In case it's a note element we play it.
var frequency = GetFrequency(noteElement.Note, noteElement.Octave);
_buzzer.PlayTone(frequency, (int)(durationInMilliseconds * 0.7));
Thread.Sleep((int)(durationInMilliseconds * 0.3));
}
Records
C # 9 inclut un nouveau type de classe appelé
enregistrement (Record). Il
présente un certain nombre d'avantages par rapport aux classes régulières, dont
la moitié est liée à une syntaxe plus concise. L' enregistrement
suivant est
tiré de la liaison
du capteur
RVB Bh1745 .
public record ChannelCompensationMultipliers(double Red, double Green, double Blue, double Clear);
Il est ensuite
utilisé un
peu plus tard dans le même fichier ,
avec une syntaxe familière:
ChannelCompensationMultipliers = new (2.2, 1.0, 1.8, 10.0);
Améliorations de l'annotation de
nullité
Les bibliothèques .NET sont maintenant complètement
annotées pour la nullité . Cela signifie que si
vous activez
la nullité ,
vous obtiendrez plus d'informations sur le type de la plate-forme pour diriger
votre utilisation de la fonctionnalité. À
l'heure actuelle, les documents
.NET n'ont
pas été entièrement annotés. Par
exemple, doit
être annoté pour prendre une string?,
tandis que String.Split (Char
[]) a
une annotation de char[]? . Nous espérons que cela
sera bientôt résolu. Des
informations complètes sont disponibles sur source.dot.net et
via les recherches de métadonnées F12 dans Visual Studio.String.IsNullOrEmpty(string)
string?
char[]?
Les packages System.Device.Gpio et Iot.Device.Bindings (version
1.1.0 pour les deux) ont également été annotés dans le cadre de cette version, à
l'aide des annotations .NET 5.0 mises à
jour. Ces bibliothèques sont toutes deux multi-ciblées,
cependant, nous utilisons la vue 5.0 pour produire des annotations pour toutes
les cibles.
Remarque: Le code .NET Core 3.1 existant peut générer
de nouveaux diagnostics (si vous avez activé la nullité) lorsque vous le
recibler vers .NET 5.0, car il existe de nouvelles
annotations.
Nous avons également ajouté de nouveaux types
d'annotations. Il
est courant pour les grandes classes d'instancier des membres d'objet dans des
méthodes d'assistance appelées à partir d'un
constructeur. Le
compilateur C # ne peut pas suivre le flux d'appels à l'affectation
d'objet. Il pensera que le membre est nul lors de la sortie du
constructeur et avertira avec CS8618
. L' attribut MemberNotNull résout
ce problème. Vous
appliquez l'attribut à la méthode d'assistance. Le compilateur verra
alors que vous définissez cette valeur et réalisera que la méthode est appelée à
partir d'un constructeur. MemberNotNullWhen est
similaire.
Vous pouvez voir un exemple de MemberNotNull
dans
les capteurs
de température BMxx80 avec
le code
suivant .
[MemberNotNull(nameof(_calibrationData))]
private void ReadCalibrationData()
{
switch (this)
{
case Bme280 _:
_calibrationData = new Bme280CalibrationData();
_controlRegister = (byte)Bmx280Register.CTRL_MEAS;
break;
case Bmp280 _:
_calibrationData = new Bmp280CalibrationData();
_controlRegister = (byte)Bmx280Register.CTRL_MEAS;
break;
case Bme680 _:
_calibrationData = new Bme680CalibrationData();
_controlRegister = (byte)Bme680Register.CTRL_MEAS;
break;
default:
throw new Exception("Bmxx80 device not correctly configured. Could not find calibraton data.");
}
_calibrationData.ReadFromDevice(this);
}
Le code
réel utilise
la compilation conditionnelle. En
effet, le projet est multi-ciblé et cet attribut n'est pris en charge qu'avec
.NET 5.0+. L'utilisation
de l'attribut permet d'ignorer les vérifications d'exécution (dans le
constructeur) qui seraient autrement nécessaires pour satisfaire les exigences
de nullabilité, comme c'est
le cas pour les versions antérieures de .NET .
Nous avons amélioré le concepteur Windows Forms,
modifié la façon dont les frameworks cibles fonctionnent pour .NET 5.0 et les
versions ultérieures, modifié la façon dont WinRT est pris en charge et apporté
d'autres améliorations.
Le concepteur Windows Forms (pour .NET Core 3.1 et
.NET 5.0) a été mis à jour dans Visual Studio 16.8 et prend désormais en charge
tous les contrôles Windows Forms. Il prend également en
charge l' interface
utilisateur Telerik pour les contrôles WinForms . Le concepteur comprend
toutes les fonctionnalités de concepteur que vous attendez, y compris:
glisser-déposer, sélection, déplacer et redimensionner, couper / copier / coller
/ supprimer des contrôles, intégration avec la fenêtre Propriétés, génération
d'événements et plus encore. La liaison de données et la prise en charge d'un
ensemble plus large de contrôles tiers seront bientôt
disponibles.
Pour en savoir
plus, consultez
la publication
du concepteur Windows
Forms pour .NET Core .
Framework cible .NET 5.0
Nous avons changé l'approche que nous utilisons
pour les
frameworks cibles avec .NET 5.0 . Le
fichier de projet suivant illustre le nouveau framework cible .NET
5.0.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
Le nouveau formulaire
est plus compact et intuitif que le style
que nous avons utilisé jusqu'à présent. De
plus, nous étendons le framework cible pour décrire les dépendances du système
d'exploitation. Ce changement est motivé par notre vision d'activer
le ciblage d'iOS et d'Android avec Xamarin dans .NET
6.0
Les API de bureau Windows (y compris Windows Forms,
WPF et WinRT) ne seront disponibles que lors du
ciblage . Vous pouvez spécifier
une version du système d'exploitation, comme ou (pour
la mise à jour d'octobre
2018 de Windows ). Vous devez cibler une
version de Windows 10 si vous souhaitez utiliser les API
WinRT
Les scénarios multiplateformes peuvent être un peu
plus difficiles lorsque vous utilisez le
nouveau TFM. System.Device.Gpio montre un modèle de gestion du
framework cible Windows si vous souhaitez éviter de créer
pour Windows ou de retirer des packages d'exécution Windows sur Linux, par
exemple
Sommaire des modifications:
net5.0
est le nouveau Target Framework Moniker (TFM) pour
.NET 5.0.
net5.0
combine
et remplace netcoreapp
et netstandard
TFM.
net5.0
prend
en charge le mode de compatibilité .NET
Framework
net5.0-windows
sera utilisé pour exposer les fonctionnalités
spécifiques à Windows, y compris les API Windows Forms, WPF et
WinRT.
- .NET
6.0 utilisera la même approche, avec ,
et ajoutera et .
net6.0
net6.0-ios
net6.0-android
- Les
TFM spécifiques au système d'exploitation peuvent inclure
des numéros
de version du système d'exploitation ,
comme .
net6.0-ios14
- Les
API portables, comme ASP.NET Core, seront utilisables
avec . Il en sera de même pour
les formulaires Xamarin avec .
net5.0
net6.0
Les modèles de Visual Studio 16.8 ciblent toujours
.NET Core 3.1, pour les applications console, WPF et Windows
Forms. Les modèles ASP.NET ont
été mis à jour pour prendre en charge .NET
5.0. Nous mettrons à jour les modèles dans Visual Studio
16.9 pour les modèles restants.
Interopérabilité WinRT (breaking change)
En ce qui concerne le ciblage des API Windows, nous
sommes passés à un nouveau
modèle de prise en charge des API WinRT dans le cadre de .NET
5.0 . Cela inclut l'appel
d'API (dans les deux sens; CLR <==> WinRT), le marshaling des données
entre les deux systèmes de types et l'unification des types qui sont destinés à
être traités de la même manière à travers le système de types ou
la limite ABI (c'est-à-dire
«types projetés »; Et sont
des exemples).IEnumerable<T>
IIterable<T>
Le système
d'interopérabilité WinRT existant a été supprimé du
runtime .NET dans le cadre de .NET 5.0. C'est
un changement radical. Cela
signifie que les applications et les bibliothèques utilisant WinRT avec .NET
Core 3.x devront être reconstruites et ne fonctionneront pas sur .NET 5.0 tel
quel. Les bibliothèques qui utilisent les API WinRT devront
multi-cibles pour gérer cette différence entre .NET Core 3.1 et .NET
5.0.
À l'avenir, nous
nous fierons
au nouvel outil
CsWinRT fourni
par l'équipe WinRT dans Windows. Il
génère des assemblys d'interopérabilité WinRT basés sur C #, qui peuvent être
fournis via NuGet. C'est
exactement ce que fait l'équipe Windows, pour les API WinRT dans
Windows. L'outil peut être utilisé par toute personne
souhaitant utiliser WinRT (sous Windows) comme système d'interopérabilité, pour
exposer les API natives aux API .NET ou .NET au code
natif.
L' outil
CsWinRT est
logiquement similaire à tlbimp et tlbexp, bien que bien
meilleur. Les
outils tlb reposaient sur un grand nombre de plomberie d'interopérabilité COM
dans le runtime .NET. L'outil
CsWinRT repose uniquement sur les API .NET
publiques. Cela
dit, la fonctionnalité
de pointeurs de fonction
en C # 9 - et partiellement implémentée dans le runtime .NET 5.0 - était en
partie inspirée par les besoins de l'outil CsWinRT.
Il y a plusieurs avantages à ce nouveau modèle
d'interopérabilité WinRT:
- Il
peut être développé et amélioré indépendamment du runtime
.NET.
- Il
est symétrique avec les systèmes d'interopérabilité basés sur des outils fournis
pour d'autres systèmes d'exploitation, comme iOS et
Android.
- L'outil
peut tirer parti d'autres fonctionnalités .NET (AOT, fonctionnalités C #,
liaison IL), ce qui n'était pas une option pour le système
précédent.
- Simplifie
la base
de code d'exécution .NET .
Vous n'avez pas besoin d'ajouter des références NuGet
pour utiliser les API WinRT. Cibler un TFM Windows
10 - dont nous venons de parler dans la section TFM .NET 5.0 précédemment -
suffit. Si
vous ciblez .NET Core 3.1 ou version antérieure, vous devez référencer les
packages WinRT. Vous
pouvez voir ce modèle dans le projet
System.Device.Gpio .
Exportations natives
Nous avons eu des demandes d'activation des
exportations pour les binaires natifs qui appellent du code .NET depuis
longtemps. Le
bloc de construction du scénario héberge
la prise en charge d'API pour UnmanagedCallersOnlyAttribute .
Cette fonctionnalité est un élément de base pour
créer des expériences de niveau
supérieur. Aaron
Robinson , de
notre équipe, a travaillé sur un projet .NET
Native Exports qui
offre une expérience plus complète pour la publication de composants .NET en
tant que bibliothèques natives. Nous recherchons des commentaires sur cette capacité
pour aider à décider si l'approche doit être incluse dans le
produit.
Le projet d'exportations natives .NET vous permet
de:
- Exposez
les exportations natives personnalisées.
- Ne
nécessite pas de technologie d'interopérabilité de niveau supérieur comme
COM.
- Fonctionne
sur plusieurs plates-formes.
Il existe des projets existants qui permettent des
scénarios similaires, tels que:
Au fil des ans, nous avons vu une variété de modèles
d'hébergement pour .NET dans les applications
natives. @rseanhall
a proposé
et implémenté un
nouveau modèle pour ce faire ,
qui tire parti de toutes les fonctionnalités d'application intégrées offertes
par la couche d'hébergement d'applications .NET (en particulier le chargement
des dépendances), tout en permettant d'appeler un point d'entrée personnalisé à
partir du code natif. C'est
parfait pour de nombreux scénarios, et on peut imaginer devenir populaire auprès
des développeurs qui hébergent des composants .NET à partir d'applications
natives. Cela
n'existait pas avant. Merci
pour la contribution, @rseanhall .
Deux PR principaux:
“Tuyau d'événements”
Event pipe est
un nouveau sous-système et une nouvelle API que nous avons ajoutés
dans .NET
Core 2.2 pour
permettre d'effectuer des analyses
de performances et
d'autres diagnostics sur
n'importe quel système d'exploitation. Dans
.NET 5.0, le canal d'événement a été étendu pour permettre aux profileurs
d'écrire des événements de canal
d'événement. Ce scénario est essentiel pour les profileurs
d'instrumentation qui s'appuyaient auparavant sur ETW (sous Windows) pour
surveiller le comportement et les performances des
applications.
Les informations de charge d'assemblage sont
désormais disponibles via le canal
d'événements. Cette
amélioration marque le début de la mise à disposition de fonctionnalités de
diagnostic similaires à celles de .NET Framework, telles
que Fusion
Log Viewer . Vous pouvez maintenant
utiliser dotnet-trace pour collecter ces informations à
l'aide de la commande suivante:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4:4 -- ./MyApp –my-arg 1
Le flux de travail est décrit dans la
documentation dotnet-trace . Vous
pouvez voir les informations de chargement d'assembly pour une application de
test simple.
Microsoft.Extensions.Logging
Nous avons apporté des améliorations au fournisseur
de journaux de console dans la bibliothèque. Vous pouvez désormais
implémenter une personnalisation pour
exercer un contrôle complet sur le formatage et la colorisation de la sortie de
la console. Les
API du formateur permettent un formatage riche en implémentant un sous-ensemble
des séquences
d'échappement (prises en charge par la plupart des terminaux
modernes). L'enregistreur de console peut analyser les séquences
d'échappement sur des terminaux non pris en charge, ce qui vous permet de créer
un formateur unique pour tous les terminaux.
En plus de la prise en charge des formateurs
personnalisés, nous avons également ajouté un formateur JSON intégré qui émet
des journaux JSON structurés vers la console.
Débogage de vidage
Le débogage du code managé nécessite la connaissance
des objets gérés et des constructions. Le
composant d'accès aux données (DAC) est un sous-ensemble du moteur d'exécution
d'exécution qui a connaissance de ces constructions et peut accéder à ces objets
gérés sans runtime. Les
vidages de processus .NET Core collectés sous Linux peuvent désormais être
analysés sous Windows à l'aide de WinDBG
ou .dotnet dump analyze
Nous avons également ajouté la prise en charge de la
capture de vidages ELF à partir de processus .NET exécutés sur
macOS. Étant donné que ELF n'est pas le lldb
format
de fichier exécutable
natif (les débogueurs natifs comme ne
fonctionneront pas avec ces vidages) sur macOS, nous en avons fait une
fonctionnalité opt-in. Pour
activer la prise en charge de la collecte de vidage sur macOS, définissez la
variable d'environnement . Les décharges
résultantes peuvent être analysées en
utilisant .COMPlus_DbgEnableElfDumpOnMacOS=1
dotnet dump analyze
Comme .NET a étendu la prise en charge des nouveaux
systèmes d'exploitation et architectures de puces, les gens veulent parfois un
moyen d'imprimer les informations sur
l'environnement. Nous avons créé un
outil .NET simple qui fait cela,
appelé dotnet-runtimeinfo .
Vous pouvez installer et exécuter l'outil avec les
commandes suivantes.
dotnet tool install -g dotnet-runtimeinfo
dotnet-runtimeinfo
L'outil produit une sortie sous la forme suivante
pour votre environnement.
**.NET information
Version: 5.0.0
FrameworkDescription: .NET 5.0.0
Libraries version: 5.0.0
Libraries hash: cf258a14b70ad9069470a108f13765e0e5988f51
**Environment information
OSDescription: Linux 5.8.6-1-MANJARO-ARM #1 SMP Thu Sep 3 22:01:08 CEST 2020
OSVersion: Unix 5.8.6.1
OSArchitecture: Arm64
ProcessorCount: 6
**CGroup info**
cfs_quota_us: -1
memory.limit_in_bytes: 9223372036854771712
memory.usage_in_bytes: 2740666368
Runtime et bibliothèques
De nombreuses améliorations ont été apportées à
l'environnement d'exécution et aux bibliothèques.
Améliorations de la qualité du code dans
RyuJIT
Il y a eu beaucoup d'améliorations au JIT dans cette
version, dont beaucoup ont été partagées dans les précédents articles de
prévisualisation .NET 5.0. Dans cet article, j'élève les changements qui sont
venus de la communauté.
Garbage Collector
Les améliorations suivantes ont été apportées au
GC.
Le GC expose maintenant des informations détaillées
sur la collection la plus récente, via la méthode GC.GetGCMemoryInfo . La structure GCMemoryInfo fournit des informations sur la
mémoire de la machine, la mémoire du tas et la collection la plus récente, ou la
collection la plus récente du type de GC que vous spécifiez - GC éphémère, à
blocage complet ou en arrière-plan.
Les cas d'utilisation les plus probables de
l'utilisation de cette nouvelle API sont la journalisation / la surveillance ou
pour indiquer à un équilibreur de chargeur qu'une machine doit être retirée de
la rotation pour demander un GC complet. Il
pourrait également être utilisé pour éviter les limites strictes des conteneurs
en réduisant la taille des caches.
Un autre changement, petit mais percutant, a été
apporté pour reporter
l' reset memory
opération coûteuse aux situations à faible
mémoire . Nous
nous attendons à ce que ces changements de politique réduisent la latence du GC
(et l'utilisation du CPU du GC en général).
Windows Arm64
Les applications .NET peuvent désormais s'exécuter en
mode natif sur Windows Arm64. Cela fait suite au
support que nous avons ajouté pour Linux Arm64 (support pour glibc et musl) avec
.NET Core 3.0. Avec
.NET 5.0, vous pouvez développer et exécuter des applications sur
les appareils
Windows Arm64, tels que Surface
Pro X . Vous pouvez déjà
exécuter des applications .NET Core et .NET Framework sur Windows Arm64, mais
via l'émulation x86. C'est réalisable, mais l'exécution native d'Arm64
offre de bien meilleures performances.
Les programmes d'installation MSI pour Arm64 ont été
l'un des derniers changements de cette
version. Vous pouvez voir le programme d'installation du SDK
.NET 5.0 dans l'image suivante.
Le SDK .NET 5.0 ne contient actuellement pas les
composants Windows Desktop - Windows Forms et WPF - sur Windows
Arm64. Cette modification a
été initialement partagée dans le post
.NET 5.0 Preview 8 . Nous espérons ajouter
le pack de bureau Windows pour Windows Arm64 dans une mise à jour de maintenance
5.0. Nous
n'avons actuellement pas de date à
partager. Jusque-là, le SDK, la console et les applications
ASP.NET Core sont pris en charge sur Windows Arm64, mais pas sur les composants
Windows Desktop.
Nous investissons considérablement dans
l'amélioration des performances d'Arm64 depuis plus d'un
an. Nous nous engageons à
faire d'Arm64 une plate-forme haute performance avec
.NET. Ces
améliorations s'appliquent également à Windows et
Linux. La
portabilité et la cohérence de la plate-forme ont toujours été des
caractéristiques convaincantes de .NET. Cela
inclut d'offrir d'excellentes performances partout où vous utilisez
.NET. Avec
.NET Core 3.x, Arm64 a la parité des fonctionnalités avec x64, mais il manque
certaines fonctionnalités et investissements clés en matière de
performances. Nous
avons résolu ce problème dans
.NET 5.0, comme décrit dans Performances d'Arm64
dans .NET 5.0 .
Les améliorations:
- Optimisations
Tune JIT pour Arm64 ( exemple )
- Activez
et tirez parti des intrinsèques du matériel Arm64
( exemple ).
- Ajustez
les algorithmes critiques pour les performances dans les bibliothèques pour
Arm64 ( exemple ).
Consultez Amélioration
des performances Arm64 dans .NET 5.0 pour
plus de détails.
Les éléments matériels
intrinsèques sont
une fonctionnalité
de performance de bas niveau que nous
avons ajoutée dans .NET Core 3.0. À
l'époque, nous avons ajouté la prise en charge des instructions et des puces
x86-64. Dans
le cadre de .NET 5.0, nous étendons la fonctionnalité pour prendre en charge
Arm64. Le
simple fait de créer les intrinsèques n'aide pas les
performances. Ils
doivent être utilisés dans un code critique pour les
performances. Nous
avons largement
exploité les propriétés intrinsèques d'Arm64 dans les
bibliothèques .NET
de .NET 5.0. Vous pouvez également le faire dans votre propre
code, bien que vous deviez vous familiariser avec les instructions du processeur
pour ce faire.
Je vais vous expliquer comment les intrinsèques du
matériel fonctionnent avec une analogie. Pour
la plupart, les développeurs s'appuient sur des types et des API intégrés à
.NET, comme ou . Ces API tirent souvent
parti des API natives du système d'exploitation, via la
fonctionnalité P
/ Invoke . P / Invoke permet une
interopérabilité native haute performance et est largement utilisé dans les
bibliothèques .NET à cette fin. Vous
pouvez utiliser cette même fonctionnalité vous-même pour appeler des API
natives. Les
intrinsèques matériels sont similaires, sauf qu'au lieu d'appeler les API du
système d'exploitation, ils vous permettent d'utiliser directement les
instructions du processeur dans votre code. C'est à peu près
équivalent à une version .NET de C
++ intrinsèquesstring.Split
HttpClient
. Les
intrinsèques matériels sont mieux considérés comme une fonction d'accélération
matérielle du processeur. Ils
offrent des avantages très tangibles et sont désormais un élément clé du
substrat de performance des bibliothèques .NET, et sont responsables de nombreux
avantages que vous pouvez lire dans l'article
sur les
performances de .NET 5.0 . En
termes de comparaison avec C ++, lorsque les éléments intrinsèques .NET sont
compilés AOT dans des fichiers prêts à l'emploi, les éléments intrinsèques n'ont
aucune pénalité en termes de performances d'exécution.
Remarque: le compilateur Visual C ++ possède
une fonctionnalité
intrinsèque analogue . Vous
pouvez comparer directement les intrinsèques matériels C ++ à .NET, comme vous
pouvez le voir si vous recherchez _mm_i32gather_epi32
sur System.Runtime.Intrinsics.X86.Avx2 , liste
des intrinsèques x64 (amd64) et guide
Intel Intrinsics . Vous
verrez beaucoup de similitudes.
Nous faisons nos premiers gros investissements dans
les performances d'Arm64 dans la version 5.0, et nous continuerons cet effort
dans les versions ultérieures. Nous travaillons
directement avec les ingénieurs d' Arm
Holdings pour
prioriser les améliorations des produits et concevoir des algorithmes qui tirent
le meilleur parti de l' Armv8
ISA . Certaines de ces
améliorations apporteront de la valeur à Arm32, cependant, nous n'appliquons pas
d'effort unique à Arm32. Si vous utilisez un Raspberry Pi, vous apprécierez
ces améliorations si vous installez la nouvelle version Arm64 du système
d'exploitation Raspberry Pi.
Nous nous attendons à ce qu'Apple annonce de nouveaux
ordinateurs Mac basés sur Apple Silicon à tout
moment. Nous disposons déjà des
premières versions de .NET
6.0 pour Apple Silicon et
avons travaillé avec les ingénieurs Apple pour aider à optimiser .NET pour cette
plate-forme. Nous
avons également eu un engagement
communautaire précoce sur Apple Silicon (Crédit @snickler ).
P95 + Latence
Nous voyons un nombre croissant de grands sites et
services accessibles sur Internet hébergés sur
.NET. Bien qu'il y ait
beaucoup d'intérêt légitime sur la métrique des requêtes par seconde
(RPS) ,
nous constatons qu'aucun grand propriétaire de site ne nous pose des questions à
ce sujet ou n'exige des millions de RPS. Cependant,
nous entendons beaucoup parler de latence, en particulier sur l'amélioration de
la latence
P95 ou P99 . Souvent, le nombre de
machines ou de cœurs provisionnés pour un site (et le plus gros facteur de coût)
est choisi en fonction de la réalisation d'une métrique P95 spécifique, par
opposition à P50. Nous pensons que la latence est la véritable
«métrique monétaire».
Nos amis de Stack Overflow font un excellent travail
de partage de données sur leur service. L'un
de leurs ingénieurs, Nick Craver, a récemment partagé
les améliorations
qu'il a apportées à la latence , suite
au passage à .NET Core :Les objets épinglés ont représenté un défi à long
terme pour les performances du GC, en particulier parce qu'ils accélèrent (ou
provoquent) la fragmentation de la
mémoire. Nous avons ajouté
un nouveau
tas GC pour les objets épinglés . Le tas
d'objets épinglés est
basé sur l'hypothèse qu'il y a très peu d'objets épinglés dans un processus mais
que leur présence entraîne des problèmes de performances
disproportionnés. Il est logique de déplacer les objets épinglés - en
particulier ceux créés par les bibliothèques .NET en tant que détail
d'implémentation - vers une zone unique, laissant les tas GC générationnels avec
peu ou pas d'objets épinglés, et avec des performances nettement supérieures en
conséquence.
Plus récemment, nous nous sommes attaqués à des défis
de longue date au sein du GC. dotnet
/ runtime # 2795 applique
une nouvelle approche à l'analyse statique GC qui évite les conflits de
verrouillage lors de la détermination de la vivacité des objets de tas
GC. dotnet
/ runtime # 25986 utilise
un nouvel algorithme pour équilibrer le travail GC entre les cœurs pendant la
phase de marquage du garbage collection, ce qui devrait augmenter le débit du
garbage collection avec de grands tas, ce qui à son tour réduit la
latence.
Nous avons travaillé sur l'amélioration de
la compilation à
plusieurs niveaux pour
plusieurs versions. Nous
continuons de le considérer comme une fonctionnalité de performance critique, à
la fois pour les performances de démarrage et en régime
permanent. Nous avons apporté deux grandes améliorations à la
compilation à plusieurs niveaux dans cette version.
Le principal mécanisme sous-jacent à la compilation à
plusieurs niveaux est le comptage des
appels. Une fois qu'une méthode
est appelée n fois, le moteur d'exécution demande au JIT de recompiler la
méthode avec une qualité supérieure. Dès
nos premières analyses de performances, nous savions que le mécanisme de
comptage des appels était trop lent, mais nous ne voyions pas de moyen simple de
résoudre ce problème. Dans
le cadre de .NET 5.0, nous avons amélioré
le mécanisme de comptage des appels utilisé
par la compilation JIT à plusieurs niveaux pour lisser les performances au
démarrage. Dans
les versions précédentes, nous avons vu des rapports de performances
imprévisibles au cours des 10 à 15 premières secondes de la durée de vie du
processus (principalement pour les serveurs
Web). Cela devrait maintenant être
résolu.
Un autre défi de performance que nous avons trouvé
était l'utilisation de la compilation à plusieurs niveaux pour les méthodes avec
des boucles. Le
problème fondamental est que vous pouvez avoir une méthode froide (appelée une
ou plusieurs fois seulement; $ lt; n) avec une boucle qui se répète plusieurs
fois. Nous
appelons ce scénario pathologique «méthode
froide; boucle
chaude ». Il est facile d'imaginer que cela se produise avec
la Main
méthode
d'une application. En conséquence, nous
avons désactivé la compilation à plusieurs niveaux pour les méthodes avec des
boucles par défaut. Au
lieu de cela, nous avons permis aux applications de choisir d'utiliser la
compilation à plusieurs niveaux avec des
boucles. PowerShell est une application qui a choisi de le
faire, après avoir constaté des améliorations de performances élevées à un
chiffre dans certains scénarios.
Pour mieux traiter les méthodes avec des boucles,
nous avons implémenté le
remplacement sur pile (OSR) . Ceci est similaire à
une fonctionnalité des machines virtuelles Java, du même
nom. OSR permet
au code exécuté par une méthode en cours d'exécution d'être recompilé au milieu
de l'exécution de la méthode, alors que ces méthodes sont actives «sur la
pile». Cette fonctionnalité est actuellement expérimentale
et opt-in, et uniquement sur x64.
Pour utiliser OSR, plusieurs fonctionnalités doivent
être activées. Le fichier
de projet PowerShell est
un bon point de départ. Vous
remarquerez que la compilation à plusieurs niveaux et toutes les fonctionnalités
de quick-jit sont activées. En outre, vous devez définir la COMPlus_TC_OnStackReplacement
variable d'environnement sur 1
.
Vous pouvez également définir les deux variables
d'environnement suivantes, en supposant que tous les autres paramètres ont leurs
valeurs par défaut:
COMPlus_TC_QuickJitForLoops=1
COMPlus_TC_OnStackReplacement=1
Nous n'avons pas l'intention d'activer OSR par défaut
dans .NET 5.0 et n'avons pas encore décidé si nous le prendrons en charge en
production.
Prise en charge de l'ICU sous
Windows
Nous utilisons
la bibliothèque ICU pour
la prise en charge d'Unicode et de la globalisation, auparavant uniquement sous
Linux et macOS. Nous
utilisons maintenant cette
même bibliothèque sous Windows 10 . Ce
changement rend
le comportement des API de globalisation telles que la comparaison de chaînes
spécifiques à la culture cohérente entre Windows 10, macOS et
Linux. Nous utilisons également ICU avec Blazor
WebAssembly.
Extension de System.DirectoryServices.Protocols à Linux
et macOS
Nous avons ajouté la prise en charge multiplateforme
pour System.DirectoryServices.Protocols . Cela inclut
la prise
en charge de Linux et
la prise
en charge de macOS . La
prise en charge de Windows était préexistante.
System.DirectoryServices.Protocols est
une API de niveau inférieur à System.DirectoryServices et
active (ou peut être utilisée pour activer) plus de
scénarios. System.DirectoryServices
inclut des concepts / implémentations Windows uniquement, donc ce n'était pas un
choix évident de faire du cross-platform. Les
deux ensembles d'API permettent de contrôler et d'interagir avec un serveur de
service d'annuaire, comme LDAP ou Active
Directory .
System.Text.Json
System.Text.Json
a
été considérablement
amélioré dans .NET 5.0 pour
améliorer les performances, la fiabilité et faciliter l'adoption par les
personnes qui connaissent Newtonsoft.Json . Il inclut également
la prise
en charge de la désérialisation des objets JSON en
enregistrements .
Si vous envisagez
d'utiliser comme
alternative à ,
vous devriez consulter le guide de
migration . Le guide clarifie la
relation entre ces deux API. est
destiné à couvrir un grand nombre des mêmes scénarios
que ,
mais il n'est pas destiné à remplacer ou à atteindre la parité des
fonctionnalités avec la bibliothèque JSON
populaire. Nous essayons de maintenir un équilibre entre les
performances et la convivialité, et le biais en faveur de la performance dans
nos choix de conception.System.Text.Json
Newtonsoft.Json
System.Text.Json
Newtonsoft.Json
HttpClient
méthodes d'extension
JsonSerializer
Les
méthodes d'extension sont
maintenant exposées HttpClient
et
simplifient considérablement l'utilisation de ces deux API
ensemble. Ces méthodes
d'extension éliminent la complexité et prennent en charge divers scénarios pour
vous, notamment la gestion du flux de contenu et la validation du type de
contenu multimédia. Steve
Gordon explique très bien les avantages de
l' envoi
et de la réception de JSON à l'aide de HttpClient avec
System.Net.Http.Json .
L'exemple suivant désérialise les données JSON de
prévisions météorologiques dans un Forecast
enregistrement,
à l'aide du nouveau
|
using System;
using System.Net.Http;
using System.Net.Http.Json;
string serviceURL = "https://localhost:5001/WeatherForecast";
HttpClient client = new();
Forecast[] forecasts = await client.GetFromJsonAsync<Forecast[]>(serviceURL);
foreach(Forecast forecast in forecasts)
{
Console.WriteLine($"{forecast.Date}; {forecast.TemperatureC}C; {forecast.Summary}");
}
// {"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}
public record Forecast(DateTime Date, int TemperatureC, int TemperatureF, string Summary); |
|
Ce code est
compact! Il repose sur des
programmes et des enregistrements de niveau supérieur de C # 9 et de la
nouvelle méthode
d'extension. L'utilisation
de et à une telle proximité
pourrait vous amener à vous demander si nous allons ajouter la prise en
charge des objets JSON en streaming . J'espère
vraiment.GetFromJsonAsync<T>()
foreach
await
Vous pouvez essayer ceci sur votre propre
machine. Les commandes du SDK
.NET suivantes créeront un service de prévisions météorologiques à l'aide du
modèle WebAPI. Il
exposera le service à l'adresse suivante par
défaut: . Il
s'agit de la même URL utilisée dans l'exemple.https://localhost:5001/WeatherForecast
rich@thundera ~ % dotnet new webapi -o webapi
rich@thundera ~ % cd webapi
rich@thundera webapi % dotnet run
Assurez-vous que vous avez exécuté
en premier
ou la poignée de main entre le client et le serveur ne fonctionnera
pas. Si
vous rencontrez des problèmes, consultez Approuver le certificat
de développement ASP.NET Core HTTPS .dotnet dev-certs
https --trust
Vous pouvez ensuite exécuter l'exemple
précédent.
rich@thundera ~ % git clone https://gist.github.com/3b41d7496f2d8533b2d88896bd31e764.git weather-forecast
rich@thundera ~ % cd weather-forecast
rich@thundera weather-forecast % dotnet run
9/9/2020 12:09:19 PM; 24C; Chilly
9/10/2020 12:09:19 PM; 54C; Mild
9/11/2020 12:09:19 PM; -2C; Hot
9/12/2020 12:09:19 PM; 24C; Cool
9/13/2020 12:09:19 PM; 45C; Balmy
Prise en charge améliorée des types
immuables
Il existe plusieurs modèles pour définir des types
immuables. Les disques ne sont que les plus
récents. JsonSerializer
prend
désormais en charge les types immuables.
Dans cet exemple, vous verrez la sérialisation avec
une structure immuable.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
var json = "{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"} ";
var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
IncludeFields = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine(forecast.Date);
Console.WriteLine(forecast.TemperatureC);
Console.WriteLine(forecast.TemperatureF);
Console.WriteLine(forecast.Summary);
var roundTrippedJson = JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine(roundTrippedJson);
public struct Forecast{
public DateTime Date {get;}
public int TemperatureC {get;}
public int TemperatureF {get;}
public string Summary {get;}
[JsonConstructor]
public Forecast(DateTime date, int temperatureC, int temperatureF, string summary) => (Date, TemperatureC, TemperatureF, Summary) = (date, temperatureC, temperatureF, summary);
}
Remarque: L'attribut JsonConstructor
est requis pour spécifier le constructeur à utiliser avec les
structures. Avec
les classes, s'il n'y a qu'un seul constructeur, l'attribut n'est pas
obligatoire. Même chose avec les
enregistrements.
Il produit la sortie
suivante:
rich@thundera jsonserializerimmutabletypes % dotnet run
9/6/2020 11:31:01 AM
-1
31
Scorching
{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}
Prise en charge des
enregistrements
JsonSerializer
la
prise en charge des enregistrements est
presque la même que celle que je viens de vous montrer pour les types
immuables. La différence que je veux montrer ici est la
désérialisation d'un objet JSON en un enregistrement qui expose un constructeur
paramétré et une propriété init facultative.
Voici le programme, y compris la définition de
l'enregistrement:
using System;
using System.Text.Json;
Forecast forecast = new(DateTime.Now, 40)
{
Summary = "Hot!"
};
string forecastJson = JsonSerializer.Serialize<Forecast>(forecast);
Console.WriteLine(forecastJson);
Forecast? forecastObj = JsonSerializer.Deserialize<Forecast>(forecastJson);
Console.Write(forecastObj);
public record Forecast (DateTime Date, int TemperatureC)
{
public string? Summary {get; init;}
};
Il produit la sortie
suivante:
rich@thundera jsonserializerrecords % dotnet run
{"Date":"2020-09-12T18:24:47.053821-07:00","TemperatureC":40,"Summary":"Hot!"}
Forecast { Date = 9/12/2020 6:24:47 PM, TemperatureC = 40, Summary = Hot! }
Amélioration de soutienDictionary<K,V>
JsonSerializer
prend désormais
en charge les
dictionnaires avec des clés sans chaîne . Vous pouvez voir à quoi
cela ressemble dans l'exemple suivant. Avec
.NET Core 3.0, ce code compile mais lève un fichier NotSupportedException
.
using System;
using System.Collections.Generic;
using System.Text.Json;
Dictionary<int, string> numbers = new ()
{
{0, "zero"},
{1, "one"},
{2, "two"},
{3, "three"},
{5, "five"},
{8, "eight"},
{13, "thirteen"},
{21, "twenty one"},
{34, "thirty four"},
{55, "fifty five"},
};
var json = JsonSerializer.Serialize<Dictionary<int, string>>(numbers);
Console.WriteLine(json);
var dictionary = JsonSerializer.Deserialize<Dictionary<int, string>>(json);
Console.WriteLine(dictionary[55]);
Il produit la sortie
suivante.
rich@thundera jsondictionarykeys % dotnet run
{"0":"zero","1":"one","2":"two","3":"three","5":"five","8":"eight","13":"thirteen","21":"twenty one","34":"thirty four","55":"fifty five"}
fifty five
Prise en charge des champs
JsonSerializer
prend désormais
en charge les
champs . Ce changement a été
apporté par @YohDeadfall . Merci!
Vous pouvez voir à quoi cela ressemble dans l'exemple
suivant. Avec .NET Core 3.0, la JsonSerializer
sérialisation
ou la désérialisation échoue avec des types qui utilisent des
champs. C'est un problème pour
les types existants qui ont des champs et ne peuvent pas être
modifiés. Avec ce changement, ce n'est plus un
problème.
using System;
using System.Text.Json;
var json = "{\"date\":\"2020-09-06T11:31:01.923395-07:00\",\"temperatureC\":-1,\"temperatureF\":31,\"summary\":\"Scorching\"} ";
var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
IncludeFields = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine(forecast.Date);
Console.WriteLine(forecast.TemperatureC);
Console.WriteLine(forecast.TemperatureF);
Console.WriteLine(forecast.Summary);
var roundTrippedJson = JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine(roundTrippedJson);
public class Forecast{
public DateTime Date;
public int TemperatureC;
public int TemperatureF;
public string Summary;
}
Produit la sortie suivante :
rich@thundera jsonserializerfields % dotnet run
9/6/2020 11:31:01 AM
-1
31
Scorching
{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}
Préserver les références dans les graphiques d'objets
JSON
JsonSerializer
a
ajouté la prise
en charge de la préservation des références
(circulaires) dans
les graphiques d'objets JSON. Pour ce faire, il stocke les ID qui peuvent être
reconstitués lorsqu'une chaîne JSON est désérialisée en
objets.
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
Employee janeEmployee = new()
{
Name = "Jane Doe",
YearsEmployed = 10
};
Employee johnEmployee = new()
{
Name = "John Smith"
};
janeEmployee.Reports = new List<Employee> { johnEmployee };
johnEmployee.Manager = janeEmployee;
JsonSerializerOptions options = new()
{
// NEW: globally ignore default values when writing null or default
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
// NEW: globally allow reading and writing numbers as JSON strings
NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString,
// NEW: globally support preserving object references when (de)serializing
ReferenceHandler = ReferenceHandler.Preserve,
IncludeFields = true, // NEW: globally include fields for (de)serialization
WriteIndented = true,};
string serialized = JsonSerializer.Serialize(janeEmployee, options);
Console.WriteLine($"Jane serialized: {serialized}");
Employee janeDeserialized = JsonSerializer.Deserialize<Employee>(serialized, options);
Console.Write("Whether Jane's first report's manager is Jane: ");
Console.WriteLine(janeDeserialized.Reports[0].Manager == janeDeserialized);
public class Employee
{
// NEW: Allows use of non-public property accessor.
// Can also be used to include fields "per-field", rather than globally with JsonSerializerOptions.
[JsonInclude]
public string Name { get; internal set; }
public Employee Manager { get; set; }
public List<Employee> Reports;
public int YearsEmployed { get; set; }
// NEW: Always include when (de)serializing regardless of global options
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public bool IsManager => Reports?.Count > 0;
}
Performance
JsonSerializer:
les
performances sont considérablement améliorées dans .NET
5.0. Stephen Toub a couvert certaines JsonSerializer
améliorations dans
son article sur les améliorations
des performances dans .NET 5 . J'ai également
couvert Json
Performance plus
en détail dans le post .NET
5.0 RC1 .
Déploiement d'applications
Après avoir écrit ou mis à jour une application, vous
devez la déployer pour
que vos utilisateurs en bénéficient. Il
peut s'agir d'un serveur Web, d'un service cloud ou d'un ordinateur client, et
peut être le résultat d'un flux CI / CD utilisant un service
comme Azure
DevOps ou GitHub
Actions .
Nous nous efforçons de fournir des capacités de
déploiement de première classe qui s'alignent naturellement sur les types
d'applications. Pour .NET 5.0, nous nous sommes concentrés sur
l'amélioration des applications à fichier unique, la réduction de la taille du
conteneur pour les builds multi-étapes de docker et une meilleure prise en
charge du déploiement d'applications ClickOnce avec .NET
Core.
Conteneurs
Nous considérons les conteneurs comme la tendance
cloud la plus importante et avons investi considérablement dans cette
modalité. Nous investissons dans
des conteneurs de plusieurs manières, à plusieurs niveaux de la pile logicielle
.NET. Le premier est notre investissement dans les
fondamentaux, qui est de plus en plus influencé par le scénario du conteneur et
par les développeurs qui déploient des applications
conteneurisées.
Nous facilitons le travail avec les orchestrateurs de
conteneurs. Nous
avons ajouté la prise
en charge d'OpenTelemetry afin
que vous puissiez capturer des traces et
des métriques distribuées à partir de votre application . dotnet-monitor est
un nouvel outil conçu comme le principal moyen d'accéder aux informations de
diagnostic à partir d'un processus .NET. En
particulier, nous avons commencé à créer une variante
de conteneur de dotnet-monitor que
vous pouvez utiliser comme side-car
d'application . Enfin, nous
développons dotnet /
tye comme
moyen d'améliorer la productivité des développeurs de microservices, à la fois
pour le développement et le déploiement dans un environnement
Kubernetes.
Le runtime .NET prend désormais
en charge
cgroup v2 ,
qui, selon nous, deviendra une API importante liée aux conteneurs au-delà de
2020. Docker utilise actuellement cgroup v1 (qui est déjà pris en charge par
.NET). En
comparaison, cgroup v2 est plus simple, plus efficace et plus sécurisé que
cgroup v1. Vous
pouvez en savoir plus sur les
limites des ressources cgroup et Docker dans
notre mise à jour Docker 2019. Les
distributions Linux et les environnements d'exécution des conteneurs sont
en train
d'ajouter la prise en charge de cgroup v2 . .NET 5.0 fonctionnera
correctement dans les environnements cgroup v2 une fois qu'ils deviendront plus
courants. Crédit Omair
Majid ,
qui prend en charge .NET à Red Hat.
Nous publions
maintenant des
images Windows Server Core , en
plus de Nano Server. Nous
avons ajouté Server Core car nous avons entendu les commentaires de clients qui
souhaitaient une image .NET entièrement compatible avec Windows
Server. Si
vous en avez besoin, cette nouvelle image est faite pour
vous. Il
est pris en charge pour la combinaison de: Windows Server 2019 Long-Term
Servicing Channel (LTSC), .NET 5.0 et x64. Nous
avons apporté d'autres modifications qui réduisent
la taille des images Windows Server Core . Ces améliorations font
une grande différence, mais ont été apportées après la sortie de Windows Server
2019. Ils bénéficieront cependant de la prochaine version
de Windows Server LTSC.
Dans le cadre du passage à «.NET» comme nom de
produit, nous publions désormais des images .NET Core 2.1, 3.1 et .NET 5.0 dans
la famille
des dépôts, au lieu de . Nous continuerons la
double publication .NET Core 2.1 et 3.1 vers l'emplacement précédent tant que
ces versions sont prises en charge. Les
images .NET 5.0 ne seront publiées que vers les nouveaux
emplacements. Veuillez
mettre à jour vos déclarations et scripts en
conséquence.mcr.microsoft.com/dotnet
mcr.microsoft.com/dotnet/core
FROM
Dans le cadre de .NET 5.0, nous
avons re-basé
l'image du SDK au-dessus de l'image ASP.NET au
lieu de buildpack-deps pour
réduire considérablement la taille des images agrégées que
vous extrayez dans
des scénarios de génération en plusieurs étapes.
Cette modification présente l'avantage suivant pour
les versions en plusieurs étapes, avec un exemple
de fichier
Dockerfile :
Coûts de construction en plusieurs étapes
avec Ubuntu 20.04
Focal :
Extraire
l'image |
Avant |
Après |
sdk:5.0-focal |
268 Mo |
232 Mo |
aspnet:5.0-focal |
64 Mo |
10 Ko (manifeste
uniquement) |
Économies
nettes de téléchargement :
100 Mo (-30%)
Coûts de construction en plusieurs étapes
avec Debian 10
Buster :
Extraire
l'image |
Avant |
Après |
sdk:5.0 |
280 Mo |
218 Mo |
aspnet:5.0 |
84 Mo |
4 Ko (manifeste
uniquement) |
Économies
nettes de téléchargement :
146 Mo (-40%)
Voir dotnet
/ dotnet-docker # 1814 pour
plus d'informations.
Cette modification facilite les builds en plusieurs
étapes, où l' image sdk
et
l' image aspnet
ou
que runtime
vous
ciblez sont la même version (nous nous attendons à ce que ce soit le cas
courant). Avec ce changement, le aspnet
pull
(par exemple), sera un no-op, car vous aurez tiré les aspnet
couches
via le sdk
pull initial .
Nous avons apporté des modifications similaires
pour Alpine
et Nano Server . Il n'y a pas
d' image
pour Alpine ou Nano Server. Cependant,
les images
pour Alpine et Nano Server n'étaient pas précédemment construites sur l'image
ASP.NET. Nous
avons corrigé cela. Vous verrez des gains de taille significatifs pour
Alpine et Nano Server ainsi qu'avec la version 5.0, pour les versions en
plusieurs étapes.buildpack-deps
sdk
Applications à fichier unique
Les applications à fichier
unique sont
publiées et déployées sous forme
de fichier unique . L'application et ses
dépendances sont toutes incluses dans ce
fichier. Lorsque l'application est exécutée, les dépendances
sont chargées directement à partir de ce fichier en mémoire (sans pénalité de
performances).
Dans .NET 5.0, les applications à fichier unique sont
principalement axées sur Linux (nous en parlerons plus
tard). Ils peuvent être
dépendants du cadre ou autonomes. Les
applications de fichier unique dépendant de Framework peuvent être très petites,
en s'appuyant sur un runtime .NET installé
globalement. Les
applications autonomes à un seul fichier sont plus volumineuses (en raison de
l'exécution du runtime), mais ne nécessitent pas l'installation du runtime .NET
comme étape préalable à l'installation et fonctionneront simplement en
conséquence. En général, la fonction dépendante de
l'infrastructure est bonne pour les environnements de développement et
d'entreprise, tandis que l'autonomie est souvent un meilleur choix pour les
éditeurs de logiciels indépendants.
Nous avons produit une version d'applications à
fichier unique avec .NET Core 3.1. Il regroupe les
binaires dans un seul fichier pour le déploiement, puis décompresse ces fichiers
dans un répertoire temporaire pour les charger et les
exécuter. Il peut y avoir des scénarios où cette approche est
meilleure, mais nous prévoyons que la solution que nous avons créée pour 5.0
sera préférée et une amélioration bienvenue.
Nous avons eu plusieurs obstacles à surmonter pour
créer une véritable solution à fichier
unique. Les tâches principales
consistaient à créer un bundler d'applications plus sophistiqué et à apprendre
au runtime à charger des assemblys à partir de ressources
binaires. Nous avons également rencontré des obstacles que nous
n'avons pas pu franchir.
Sur toutes les plateformes, nous avons un composant
appelé «apphost». C'est le fichier qui
devient votre exécutable, par exemple sous
Windows oumyapp.exe
./myapp
sur
les plates-formes Unix. Pour les applications à
fichier unique, nous avons créé un nouvel hôte d'application que nous appelons
«superhost». Il
a le même rôle que l'hôte d'appli standard, mais comprend également une copie
liée statiquement du runtime. Le
superhôte est un point de conception fondamental de notre approche de fichier
unique. Ce
modèle est celui que nous utilisons sous Linux avec .NET
5.0. Nous
n'avons pas pu implémenter cette approche sous Windows ou macOS, en raison de
diverses contraintes du système d'exploitation. Nous n'avons pas de
superhôte sur Windows ou macOS. Sur
ces systèmes d'exploitation, les binaires d'exécution natifs (~ 3 d'entre eux)
se trouvent à côté de l'application de fichier unique (ce qui entraîne «pas un
seul fichier»). Nous allons revoir cette situation dans .NET 6.0,
cependant, nous nous attendons à ce que les problèmes que nous avons rencontrés
restent difficiles.
Vous pouvez utiliser les commandes suivantes pour
créer des applications à fichier unique.
- Application
à un seul fichier dépendante du framework:
dotnet publish -r
linux-x64 --self-contained false /p:PublishSingleFile=true
- Application
mono-fichier autonome:
dotnet publish -r
linux-x64 --self-contained true /p:PublishSingleFile=true
Vous pouvez également configurer la publication de
fichier unique avec un fichier de projet.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<!-- The OS and CPU type you are targeting -->
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<!-- Determine self-contained or framework-dependent -->
<SelfContained>true</SelfContained>
<!-- Enable single file -->
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
</Project>
Vous pouvez expérimenter
la découpe
d'assemblage pour
réduire la taille de votre application. Il
peut interrompre les applications en les coupant excessivement, il est donc
recommandé de tester soigneusement votre application après avoir utilisé cette
fonctionnalité. Le
découpage d'assembly supprime également le code natif en lecture-exécution
compilé à l'avance (pour les assemblys découpés), qui est principalement destiné
aux performances. Vous
souhaiterez tester les performances de votre application après le
découpage. Vous pouvez compiler votre application prête à
exécuter après le trimmng en utilisant PublishReadyToRun
property
(et en définissant sur true
) .You
can ready-to-run-compile your app after trimmng by
using property
(and setting to ).
Remarques:
- Les
applications sont spécifiques au système d'exploitation et à
l'architecture. Vous devez publier pour chaque configuration (Linux
x64, Linux Arm64, Windows x64,…).
- Les
fichiers de configuration (comme ) sont inclus dans le
fichier unique. Vous pouvez placer un fichier de configuration
supplémentaire à côté du fichier unique, si nécessaire (éventuellement pour des
tests).
*.runtimeconfig.json
.pdb
les
fichiers ne sont pas inclus dans le fichier unique par
défaut. Vous pouvez activer
l'incorporation PDB avec la propriété.<DebugType>embed</DebugType>
- La
IncludeNativeLibrariesForSelfExtract
propriété peut être utilisée
pour incorporer
des binaires d'exécution natifs ,
sous Windows et macOS, cependant, ils doivent être décompressés dans un stockage
temporaire au moment de l'exécution. Cette
fonctionnalité n'est pas recommandée pour une utilisation
générale.
ClickOnce
ClickOnce est
une option de déploiement .NET populaire depuis de nombreuses
années. Il
est désormais pris en charge pour les applications Windows .NET Core 3.1 et .NET
5.0. Nous
savions que de nombreuses personnes souhaiteraient utiliser ClickOnce pour le
déploiement d'applications lorsque nous avons ajouté la prise en charge de
Windows Forms et de WPF à .NET Core 3.0. Au
cours de l'année écoulée, les équipes .NET et Visual Studio ont travaillé
ensemble pour activer la publication ClickOnce, à la fois en ligne de commande
et dans Visual Studio.
Nous avions deux objectifs dès le début du
projet:
- Activez
une expérience familière pour ClickOnce dans Visual
Studio.
- Activez
un CI / CD moderne pour la publication ClickOnce avec des flux de ligne de
commande, avec MSBuild ou l'outil Mage.
Il est plus simple de vous montrer l'expérience en
images.
Commençons par l'expérience Visual Studio, centrée
sur la publication de projets.
Le modèle de déploiement principal que nous prenons
actuellement en charge est celui des
applications dépendant du framework . Il est facile de
prendre une dépendance sur le .NET Desktop Runtime (c'est celui qui contient WPF
et Windows Forms). Votre
programme d'installation ClickOnce installera le runtime .NET sur les machines
des utilisateurs si nécessaire. Nous avons également l'intention de prendre en charge
les applications autonomes et à fichier unique.
Vous vous demandez peut-être si vous pouvez toujours
profiter de ClickOnce hors ligne et des fonctionnalités de mise à
jour. Oui, vous pouvez.
Le grand changement
avec Mage est
qu'il s'agit désormais d'un outil .NET, distribué sur
NuGet. Cela
signifie que vous n'avez pas besoin d'installer quoi que ce soit de spécial sur
votre machine. Vous
avez juste besoin du SDK .NET 5.0 et vous pouvez ensuite installer Mage en tant
qu'outil .NET. Vous pouvez également l'utiliser pour publier des
applications .NET Framework, mais la signature SHA1 et la prise en charge de la
confiance partielle ont été supprimées.
La commande d'installation de Mage
suit:
dotnet tool install -g Microsoft.DotNet.Mage
Une fois que vous avez produit et distribué votre
programme d'installation ClickOnce, vos utilisateurs verront les boîtes de
dialogue d'installation ClickOnce familières.
Vos utilisateurs verront la boîte de dialogue de mise
à jour lorsque vous rendrez les mises à jour
disponibles.
Conclusion
.NET 5.0 est une autre version importante qui devrait
améliorer de nombreux aspects de votre utilisation avec
.NET. Nous avons permis un
large éventail d'améliorations, allant des applications à fichier unique aux
performances, en passant par l'utilisation de la sérialisation Json et
l'activation Arm64. Bien
qu'aujourd'hui soit votre premier jour avec .NET 5.0, nous exécutons .NET 5.0 en
production chez Microsoft depuis des mois. Nous
sommes convaincus qu'il est prêt à être utilisé, à gérer votre entreprise et à
alimenter vos applications. Les
nouvelles améliorations du langage en C # 9 et F # 5 devraient rendre votre code
plus expressif et plus facile à écrire. .NET
5.0 est également un excellent choix pour vos applications
existantes. Dans de nombreux cas, vous pouvez effectuer une mise
à niveau sans trop d'effort.
Si vous êtes intéressé par la performance, vous
pourriez être intéressé par nos progrès avec
les benchmarks
TechEmpower . Avec le recul, vous
pouvez voir que .NET
Core 3.1 se porte plutôt bien avec le round 19 , le
dernier round. Nous
sommes impatients de voir .NET 5.0 dans le
prochain round 20 . Le
nouveau classement sera à surveiller lorsque la 20e manche sera finalisée et
publiée.
Les améliorations apportées à .NET 5.0 sont le
résultat des efforts de nombreuses personnes, travaillant en collaboration à
travers le monde et dans de nombreux fuseaux horaires, sur
GitHub. Merci à tous ceux qui
ont contribué à cette version. Et
ne vous inquiétez pas, il existe de nombreuses opportunités de
contribuer. La
version .NET 5.0 est arrivée à son terme,
mais la
prochaine version a déjà commencé .
***fin de traduction du billet de Richard***
OD : On se retrouve bientôt sur tous ces sujets, alors Stay Tuned !