Delen via


Wat is er nieuw in .NET Core 3.0?

In dit artikel wordt beschreven wat er nieuw is in .NET Core 3.0. Een van de grootste verbeteringen is ondersteuning voor Windows-bureaubladtoepassingen (alleen Windows). Met het .NET Core 3.0 SDK-onderdeel Windows Desktop kunt u uw Windows Forms- en Windows Presentation Foundation-toepassingen (WPF) overzetten. Om duidelijk te zijn, wordt het Windows-bureaubladonderdeel alleen ondersteund en opgenomen in Windows. Zie de windows-bureaubladsectie verderop in dit artikel voor meer informatie.

.NET Core 3.0 voegt ondersteuning toe voor C# 8.0. Het wordt ten zeerste aanbevolen om Visual Studio 2019 versie 16.3 of hoger te gebruiken, of Visual Studio Code met de nieuwste C#-extensie.

Download en ga op dit moment aan de slag met .NET Core 3.0 in Windows, macOS of Linux.

Zie de aankondiging van .NET Core 3.0 voor meer informatie over de release.

.NET Core 3.0 RC 1 werd beschouwd als productieklaar door Microsoft en werd volledig ondersteund. Als u een preview-versie gebruikt, moet u naar de RTM-versie gaan voor continue ondersteuning.

Taalverbeteringen C# 8.0

C# 8.0 maakt ook deel uit van deze release, waaronder de functie voor null-verwijzingstypen , asynchrone streams en meer patronen. Zie wat er nieuw is in C# 8.0 voor meer informatie over C# 8.0-functies.

Zelfstudies met betrekking tot C# 8.0-taalfuncties:

Taalverbeteringen zijn toegevoegd ter ondersteuning van de volgende API-functies die hieronder worden beschreven:

.NET Standard 2.1

.NET Core 3.0 implementeert .NET Standard 2.1. Met de standaardsjabloon dotnet new classlib wordt echter een project gegenereerd dat nog steeds gericht is op .NET Standard 2.0. Als u .NET Standard 2.1 wilt gebruiken, bewerkt u het projectbestand en wijzigt u de TargetFramework eigenschap innetstandard2.1:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
  </PropertyGroup>

</Project>

Als u Visual Studio gebruikt, hebt u Visual Studio 2019 nodig, omdat Visual Studio 2017 geen ondersteuning biedt voor .NET Standard 2.1 of .NET Core 3.0.

Compileren/implementeren

Standaard uitvoerbare bestanden

.NET Core bouwt nu standaard frameworkafhankelijke uitvoerbare bestanden . Dit gedrag is nieuw voor toepassingen die gebruikmaken van een wereldwijd geïnstalleerde versie van .NET Core. Voorheen zouden alleen zelfstandige implementaties een uitvoerbaar bestand produceren.

Tijdens dotnet build of dotnet publishwordt een uitvoerbaar bestand (ook wel appHost genoemd) gemaakt dat overeenkomt met de omgeving en het platform van de SDK die u gebruikt. U kunt dezelfde dingen verwachten met deze uitvoerbare bestanden als andere systeemeigen uitvoerbare bestanden, zoals:

  • U kunt dubbelklikken op het uitvoerbare bestand.
  • U kunt de toepassing rechtstreeks starten vanaf een opdrachtprompt, zoals myapp.exe in Windows en ./myapp in Linux en macOS.

macOS appHost en notarisatie

alleen macOS

Vanaf de notarized .NET Core SDK 3.0 voor macOS is de instelling voor het produceren van een standaard uitvoerbaar bestand (ook wel appHost genoemd) standaard uitgeschakeld. Zie macOS Catalina Notarization en de impact op .NET Core-downloads en -projecten voor meer informatie.

Wanneer de appHost-instelling is ingeschakeld, genereert .NET Core een systeemeigen Mach-O-uitvoerbaar bestand wanneer u bouwt of publiceert. Uw app wordt uitgevoerd in de context van de appHost wanneer deze wordt uitgevoerd vanuit de broncode met de dotnet run opdracht of door het uitvoerbare bestand Mach-O rechtstreeks te starten.

Zonder de appHost kan een gebruiker alleen een frameworkafhankelijke app starten met de dotnet <filename.dll> opdracht. Er wordt altijd een appHost gemaakt wanneer u uw app zelf publiceert.

U kunt de appHost op projectniveau configureren of de appHost in-/uitschakelen voor een specifieke dotnet opdracht met de -p:UseAppHost parameter:

  • Projectbestand

    <PropertyGroup>
      <UseAppHost>true</UseAppHost>
    </PropertyGroup>
    
  • Opdrachtregelparameter

    dotnet run -p:UseAppHost=true
    

Zie MSBuild-eigenschappen voor Microsoft.NET.Sdk voor meer informatie over de UseAppHost instelling.

Uitvoerbare bestanden met één bestand

De dotnet publish opdracht ondersteunt het verpakken van uw app in een platformspecifiek uitvoerbaar bestand met één bestand. Het uitvoerbare bestand kan zelf worden geëxtraheerd en bevat alle afhankelijkheden (inclusief systeemeigen) die nodig zijn om uw app uit te voeren. Wanneer de app voor het eerst wordt uitgevoerd, wordt de toepassing geëxtraheerd naar een map op basis van de app-naam en build-id. Het opstarten is sneller wanneer de toepassing opnieuw wordt uitgevoerd. De toepassing hoeft zichzelf geen tweede keer te extraheren, tenzij er een nieuwe versie is gebruikt.

Als u een uitvoerbaar bestand met één bestand wilt publiceren, stelt u het PublishSingleFile in uw project of op de opdrachtregel in met de dotnet publish opdracht:

<PropertyGroup>
  <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
  <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

– of –

dotnet publish -r win10-x64 -p:PublishSingleFile=true

Zie het ontwerpdocument met één bestandsbundel voor meer informatie over het publiceren van één bestand.

Montage bijsnijden

De .NET Core 3.0 SDK wordt geleverd met een hulpprogramma waarmee de grootte van apps kan worden verkleind door IL te analyseren en ongebruikte assembly's te knippen.

Zelfstandige apps bevatten alles wat nodig is om uw code uit te voeren, zonder dat .NET moet worden geïnstalleerd op de hostcomputer. Vaak vereist de app echter slechts een kleine subset van het framework om te functioneren en kunnen andere ongebruikte bibliotheken worden verwijderd.

.NET Core bevat nu een instelling waarmee het IL Trimmer-hulpprogramma wordt gebruikt om de IL van uw app te scannen. Met dit hulpprogramma wordt gedetecteerd welke code is vereist en worden ongebruikte bibliotheken vervolgens beperkt. Dit hulpprogramma kan de implementatiegrootte van sommige apps aanzienlijk verminderen.

Als u dit hulpprogramma wilt inschakelen, voegt u de <PublishTrimmed> instelling in uw project toe en publiceert u een zelfstandige app:

<PropertyGroup>
  <PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
dotnet publish -r <rid> -c Release

Als voorbeeld is de basissjabloon 'hallo wereld' van het nieuwe consoleproject die is opgenomen, wanneer deze wordt gepubliceerd, ongeveer 70 MB groot. Door deze grootte te gebruiken <PublishTrimmed>, wordt deze verkleind tot ongeveer 30 MB.

Het is belangrijk om na te denken dat toepassingen of frameworks (inclusief ASP.NET Core en WPF) die gebruikmaken van weerspiegeling of gerelateerde dynamische functies, vaak breken wanneer ze worden ingekort. Deze onderbreking treedt op omdat de trimmer niet weet over dit dynamische gedrag en niet kan bepalen welke frameworktypen vereist zijn voor reflectie. Het IL Trimmer-hulpprogramma kan worden geconfigureerd om rekening te houden met dit scenario.

Zorg er vooral voor dat u uw app test na het bijsnijden.

Zie de documentatie of ga naar de mono/linker-opslagplaats voor meer informatie over het IL Trimmer-hulpprogramma.

Gelaagde compilatie

Gelaagde compilatie (TC) is standaard ingeschakeld met .NET Core 3.0. Met deze functie kan de runtime de Just-In-Time-compiler (Just-In-Time) beter gebruiken om betere prestaties te bereiken.

Het belangrijkste voordeel van gelaagde compilatie is om twee manieren van jitting-methoden te bieden: in een lagere kwaliteit-maar-snellere laag of een hogere kwaliteit-maar-tragere laag. De kwaliteit verwijst naar hoe goed de methode is geoptimaliseerd. TC helpt bij het verbeteren van de prestaties van een toepassing tijdens het doorlopen van verschillende uitvoeringsfasen, van opstarten tot een stabiele status. Wanneer gelaagde compilatie is uitgeschakeld, wordt elke methode op één manier gecompileerd die vooroordelen heeft ten opzichte van de opstartprestaties.

Wanneer TC is ingeschakeld, is het volgende gedrag van toepassing op methodecompilatie wanneer een app wordt gestart:

  • Als de methode vooraf gecompileerde code of ReadyToRun bevat, wordt de vooraf gegenereerde code gebruikt.
  • Anders wordt de methode gestippeld. Deze methoden zijn doorgaans algemene waarden voor waardetypen.
    • Snelle JIT produceert sneller (of minder geoptimaliseerde) code van lagere kwaliteit. In .NET Core 3.0 is Snelle JIT standaard ingeschakeld voor methoden die geen lussen bevatten en de voorkeur hebben tijdens het opstarten.
    • De volledig optimaliserende JIT produceert langzamere (of meer geoptimaliseerde) code van hogere kwaliteit. Voor methoden waarbij Quick JIT niet wordt gebruikt (bijvoorbeeld als de methode wordt toegeschreven aan MethodImplOptions.AggressiveOptimization), wordt het volledig optimaliseren van JIT gebruikt.

Voor veelgebruikte methoden maakt de Just-In-Time-compiler uiteindelijk volledig geoptimaliseerde code op de achtergrond. De geoptimaliseerde code vervangt vervolgens de vooraf gecompileerde code voor die methode.

Code die door Quick JIT wordt gegenereerd, kan langzamer worden uitgevoerd, meer geheugen toewijzen of meer stackruimte gebruiken. Als er problemen zijn, kunt u Quick JIT uitschakelen met behulp van deze MSBuild-eigenschap in het projectbestand:

<PropertyGroup>
  <TieredCompilationQuickJit>false</TieredCompilationQuickJit>
</PropertyGroup>

Als u TC volledig wilt uitschakelen, gebruikt u deze MSBuild-eigenschap in uw projectbestand:

<PropertyGroup>
  <TieredCompilation>false</TieredCompilation>
</PropertyGroup>

Tip

Als u deze instellingen in het projectbestand wijzigt, moet u mogelijk een schone build uitvoeren om de nieuwe instellingen weer te geven (verwijder de obj mappen en bin maak ze opnieuw).

Zie Runtime-configuratieopties voor compilatie voor compilatie voor meer informatie over het configureren van compilatie tijdens runtime.

ReadyToRun-installatiekopieën

U kunt de opstarttijd van uw .NET Core-toepassing verbeteren door uw toepassingsassembly's te compileren als ReadyToRun-indeling (R2R). R2R is een vorm van AOT-compilatie (ahead-of-time).

Binaire R2R-bestanden verbeteren de opstartprestaties door de hoeveelheid werk te verminderen die de Just-In-Time-compiler (JIT) moet doen wanneer uw toepassing wordt geladen. De binaire bestanden bevatten vergelijkbare systeemeigen code vergeleken met wat de JIT zou produceren. Binaire R2R-bestanden zijn echter groter omdat ze zowel tussenliggende taalcode (IL) bevatten, die nog steeds nodig is voor sommige scenario's en de systeemeigen versie van dezelfde code. R2R is alleen beschikbaar wanneer u een zelfstandige app publiceert die gericht is op specifieke runtime-omgevingen (RID), zoals Linux x64 of Windows x64.

Ga als volgt te werk om uw project als ReadyToRun te compileren:

  1. Voeg de <PublishReadyToRun> instelling toe aan uw project:

    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
  2. Een zelfstandige app publiceren. Met deze opdracht maakt u bijvoorbeeld een zelfstandige app voor de 64-bits versie van Windows:

    dotnet publish -c Release -r win-x64 --self-contained
    

Beperkingen voor platformoverschrijdende/architectuur

De ReadyToRun-compiler biedt momenteel geen ondersteuning voor kruislingse targeting. U moet compileren op een bepaald doel. Als u bijvoorbeeld R2R-installatiekopieën voor Windows x64 wilt, moet u de opdracht Publiceren uitvoeren in die omgeving.

Uitzonderingen op kruislingse targeting:

  • Windows x64 kan worden gebruikt om Windows Arm32-, Arm64- en x86-installatiekopieën te compileren.
  • Windows x86 kan worden gebruikt om Windows Arm32-installatiekopieën te compileren.
  • Linux x64 kan worden gebruikt om Linux Arm32- en Arm64-installatiekopieën te compileren.

Zie Gereed om uit te voeren voor meer informatie.

Runtime/SDK

Runtime van primaire versie vooruitdraaien

.NET Core 3.0 introduceert een opt-in-functie waarmee uw app kan worden doorgestuurd naar de nieuwste primaire versie van .NET Core. Daarnaast is er een nieuwe instelling toegevoegd om te bepalen hoe roll forward wordt toegepast op uw app. Dit kan op de volgende manieren worden geconfigureerd:

  • Projectbestandseigenschap: RollForward
  • Eigenschap van runtimeconfiguratiebestand: rollForward
  • Omgevingsvariabele: DOTNET_ROLL_FORWARD
  • Opdrachtregelargument: --roll-forward

Een van de volgende waarden moet worden opgegeven. Als de instelling wordt weggelaten, is Minor de standaardinstelling.

  • LatestPatch
    Ga door naar de hoogste patchversie. Hierdoor wordt het terugdraaien van secundaire versies uitgeschakeld.
  • Klein
    Rol door naar de laagste hogere secundaire versie, als de aangevraagde secundaire versie ontbreekt. Als de aangevraagde secundaire versie aanwezig is, wordt het LatestPatch-beleid gebruikt.
  • Groot
    Rol door naar de laagste hogere primaire versie en de laagste secundaire versie, als de aangevraagde primaire versie ontbreekt. Als de aangevraagde primaire versie aanwezig is, wordt het secundaire beleid gebruikt.
  • LatestMinor
    Rol door naar de hoogste secundaire versie, zelfs als de aangevraagde secundaire versie aanwezig is. Bedoeld voor scenario's voor het hosten van onderdelen.
  • LatestMajor
    Rol door naar de hoogste primaire en hoogste secundaire versie, zelfs als de aangevraagde primaire versie aanwezig is. Bedoeld voor scenario's voor het hosten van onderdelen.
  • Uitschakelen
    Niet vooruitdraaien. Alleen binden aan de opgegeven versie. Dit beleid wordt niet aanbevolen voor algemeen gebruik, omdat hiermee de mogelijkheid om door te schakelen naar de nieuwste patches wordt uitgeschakeld. Deze waarde wordt alleen aanbevolen voor testen.

Naast de instelling Uitschakelen gebruiken alle instellingen de meest beschikbare patchversie.

Als de aangevraagde versie (zoals opgegeven in .runtimeconfig.json voor de toepassing) standaard een releaseversie is, worden alleen releaseversies in aanmerking genomen voor roll forward. Eventuele voorlopige versies worden genegeerd. Als er geen overeenkomende releaseversie is, worden voorlopige versies in aanmerking genomen. Dit gedrag kan worden gewijzigd door de instelling in te stellen DOTNET_ROLL_FORWARD_TO_PRERELEASE=1. In dat geval worden alle versies altijd in overweging genomen.

Afhankelijkheden van kopieën maken

Met dotnet build de opdracht worden nu NuGet-afhankelijkheden voor uw toepassing gekopieerd van de NuGet-cache naar de uitvoermap van de build. Voorheen werden afhankelijkheden alleen gekopieerd als onderdeel van dotnet publish.

Er zijn enkele bewerkingen, zoals bijsnijden en het publiceren van scheermachtigingen, die nog steeds publicatie vereisen.

Lokale hulpprogramma's

.NET Core 3.0 introduceert lokale hulpprogramma's. Lokale hulpprogramma's zijn vergelijkbaar met globale hulpprogramma's , maar zijn gekoppeld aan een bepaalde locatie op schijf. Lokale hulpprogramma's zijn niet wereldwijd beschikbaar en worden gedistribueerd als NuGet-pakketten.

Lokale hulpprogramma's zijn afhankelijk van een manifestbestandsnaam dotnet-tools.json in uw huidige map. Dit manifestbestand definieert de hulpprogramma's die beschikbaar zijn in die map en hieronder. U kunt het manifestbestand distribueren met uw code om ervoor te zorgen dat iedereen die met uw code werkt, dezelfde hulpprogramma's kan herstellen en gebruiken.

Voor zowel globale als lokale hulpprogramma's is een compatibele versie van de runtime vereist. Veel hulpprogramma's op dit moment op NuGet.org doel .NET Core Runtime 2.1. Als u deze hulpprogramma's globaal of lokaal wilt installeren, moet u de NET Core 2.1 Runtime nog steeds installeren.

Opties voor nieuwe global.json

Het bestand global.json bevat nieuwe opties die meer flexibiliteit bieden wanneer u probeert te definiëren welke versie van de .NET Core SDK wordt gebruikt. De nieuwe opties zijn:

  • allowPrerelease: Geeft aan of de SDK-resolver voorlopige versies moet overwegen bij het selecteren van de SDK-versie die moet worden gebruikt.
  • rollForward: Geeft het roll-forward-beleid aan dat moet worden gebruikt bij het selecteren van een SDK-versie, hetzij als een terugval wanneer een specifieke SDK-versie ontbreekt of als richtlijn voor het gebruik van een hogere versie.

Zie global.json overzicht voor meer informatie over de wijzigingen, waaronder standaardwaarden, ondersteunde waarden en nieuwe overeenkomende regels.

Kleinere garbagecollection-heapgrootten

De standaard heapgrootte van de garbagecollector is verminderd, wat resulteert in .NET Core met minder geheugen. Deze wijziging is beter afgestemd op het toewijzingsbudget van de generatie 0 met moderne processorcachegrootten.

Ondersteuning voor grote pagina's voor garbagecollection

Grote pagina's (ook wel bekend als Huge Pages on Linux) is een functie waarbij het besturingssysteem geheugenregio's kan instellen die groter zijn dan het systeemeigen paginaformaat (vaak 4K) om de prestaties van de toepassing die deze grote pagina's aanvraagt, te verbeteren.

De garbagecollection kan nu worden geconfigureerd met de instelling GCLargePages als opt-in-functie om grote pagina's toe te wijzen in Windows.

Windows Desktop & COM

.NET Core SDK Windows Installer

Het MSI-installatieprogramma voor Windows is gewijzigd vanaf .NET Core 3.0. De SDK-installatieprogramma's upgraden nu sdk-onderdelenbandreleases. Functiebanden worden gedefinieerd in de honderden groepen in de patchsectie van het versienummer. Bijvoorbeeld 3.0.101 en 3.0.201 zijn versies in twee verschillende functiebanden terwijl 3.0.101 en 3.0.199 bevinden zich in dezelfde functieband. En wanneer .NET Core SDK 3.0.101 is geïnstalleerd, .NET Core SDK 3.0.100 wordt van de machine verwijderd als deze bestaat. Wanneer .NET Core SDK 3.0.200 is geïnstalleerd op dezelfde computer, .NET Core SDK 3.0.101 wordt niet verwijderd.

Zie Overzicht van hoe .NET Core versiebeheer wordt uitgevoerd voor meer informatie over versiebeheer.

Windows-bureaublad

.NET Core 3.0 ondersteunt Windows-bureaubladtoepassingen met behulp van Windows Presentation Foundation (WPF) en Windows Forms. Deze frameworks ondersteunen ook het gebruik van moderne besturingselementen en Fluent-styling vanuit de Windows UI XAML Library (WinUI) via XAML-eilanden.

Het Windows Desktop-onderdeel maakt deel uit van de Windows .NET Core 3.0 SDK.

U kunt een nieuwe WPF- of Windows Forms-app maken met de volgende dotnet opdrachten:

dotnet new wpf
dotnet new winforms

Visual Studio 2019 voegt nieuwe projectsjablonen toe voor .NET Core 3.0 Windows Forms en WPF.

Zie Poort WPF-projecten en Port Windows Forms-projecten voor meer informatie over het overzetten van een bestaande .NET Framework-toepassing.

WinForms hoge DPI

.NET Core Windows Forms-toepassingen kunnen hoge DPI-modus instellen met Application.SetHighDpiMode(HighDpiMode). Met SetHighDpiMode de methode wordt de bijbehorende hoge DPI-modus ingesteld, tenzij de instelling eerder is ingesteld op andere manieren, zoals App.Manifest of P/Invoke Application.Run.

De mogelijke highDpiMode waarden, zoals uitgedrukt in de System.Windows.Forms.HighDpiMode enum, zijn:

  • DpiUnaware
  • SystemAware
  • PerMonitor
  • PerMonitorV2
  • DpiUnawareGdiScaled

Zie High DPI Desktop Application Development in Windows voor meer informatie over hoge DPI-modi.

COM-onderdelen maken

In Windows kunt u nu com-aanroepbare beheerde onderdelen maken. Deze mogelijkheid is essentieel voor het gebruik van .NET Core met COM-invoegtoepassingsmodellen en om pariteit met .NET Framework te bieden.

In tegenstelling tot .NET Framework waar de mscoree.dll als com-server is gebruikt, voegt .NET Core een systeemeigen launcher-dll toe aan de bin-map wanneer u uw COM-onderdeel bouwt.

Zie de COM-demo voor een voorbeeld van hoe u een COM-onderdeel maakt en gebruikt.

Systeemeigen Windows Interop

Windows biedt een uitgebreide systeemeigen API in de vorm van platte C API's, COM en WinRT. Hoewel .NET Core P/Invoke ondersteunt, voegt .NET Core 3.0 de mogelijkheid toe om COM-API's van CoCreate en WinRT-API's te activeren. Zie de Excel-demo voor een codevoorbeeld.

MSIX-implementatie

MSIX is een nieuwe Windows-toepassingspakketindeling. Het kan worden gebruikt voor het implementeren van .NET Core 3.0-bureaubladtoepassingen in Windows 10.

Met het Windows Application Packaging-project, dat beschikbaar is in Visual Studio 2019, kunt u MSIX-pakketten maken met zelfstandige .NET Core-toepassingen.

Het .NET Core-projectbestand moet de ondersteunde runtimes in de <RuntimeIdentifiers> eigenschap opgeven:

<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>

Linux-verbeteringen

SerialPort voor Linux

.NET Core 3.0 biedt basisondersteuning voor System.IO.Ports.SerialPort Linux.

Voorheen werd .NET Core alleen ondersteund met behulp van SerialPort Windows.

Zie GitHub-probleem 33146 voor meer informatie over de beperkte ondersteuning voor de seriële poort in Linux.

Geheugenlimieten voor Docker en cgroup

Het uitvoeren van .NET Core 3.0 op Linux met Docker werkt beter met cgroup-geheugenlimieten. Het uitvoeren van een Docker-container met geheugenlimieten, zoals met docker run -m, wijzigt hoe .NET Core zich gedraagt.

  • Standaard garbagecollection (GC) heapgrootte: maximaal 20 mb of 75% van de geheugenlimiet op de container.
  • Expliciete grootte kan worden ingesteld als een absoluut getal of percentage van de cgrouplimiet.
  • Minimale gereserveerde segmentgrootte per GC-heap is 16 mb. Deze grootte vermindert het aantal heaps dat op computers wordt gemaakt.

GPIO-ondersteuning voor Raspberry Pi

Er zijn twee pakketten uitgebracht voor NuGet die u kunt gebruiken voor GPIO-programmering:

De GPIO-pakketten omvatten API's voor GPIO-, SPI-, I2C- en PWM-apparaten . Het IoT-bindingspakket bevat apparaatbindingen. Zie de GitHub-opslagplaats voor apparaten voor meer informatie.

Ondersteuning voor Arm64 Linux

.NET Core 3.0 voegt ondersteuning toe voor Arm64 voor Linux. De primaire use case voor Arm64 is momenteel met IoT-scenario's. Zie .NET Core Arm64-status voor meer informatie.

Docker-installatiekopieën voor .NET Core op Arm64 zijn beschikbaar voor Alpine, Debian en Ubuntu.

Notitie

Ondersteuning voor macOS Arm64 (of 'Apple Silicon') en Windows Arm64-besturingssystemen is later toegevoegd in .NET 6.

Beveiliging

TLS 1.3 & OpenSSL 1.1.1 op Linux

.NET Core maakt nu gebruik van TLS 1.3-ondersteuning in OpenSSL 1.1.1 wanneer deze beschikbaar is in een bepaalde omgeving. Met TLS 1.3:

  • Verbindingstijden worden verbeterd met minder retouren die nodig zijn tussen de client en de server.
  • Verbeterde beveiliging vanwege het verwijderen van verschillende verouderde en onveilige cryptografische algoritmen.

Indien beschikbaar, gebruikt .NET Core 3.0 OpenSSL 1.1.1, OpenSSL 1.1.0 of OpenSSL 1.0.2 op een Linux-systeem. Wanneer OpenSSL 1.1.1 beschikbaar is, gebruiken beide System.Net.Security.SslStream typen System.Net.Http.HttpClient TLS 1.3 (ervan uitgaande dat zowel de client als de server TLS 1.3 ondersteunen).

In het volgende C# 8.0-voorbeeld ziet u hoe .NET Core 3.0 op Ubuntu 18.10 verbinding maakt met https://www.cloudflare.com:

using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace whats_new
{
    public static class TLS
    {
        public static async Task ConnectCloudFlare()
        {
            var targetHost = "www.cloudflare.com";

            using TcpClient tcpClient = new TcpClient();

            await tcpClient.ConnectAsync(targetHost, 443);

            using SslStream sslStream = new SslStream(tcpClient.GetStream());

            await sslStream.AuthenticateAsClientAsync(targetHost);
            await Console.Out.WriteLineAsync($"Connected to {targetHost} with {sslStream.SslProtocol}");
        }
    }
}

Cryptografie-coderingen

.NET Core 3.0 voegt ondersteuning toe voor AES-GCM - en AES-CCM-coderingen , geïmplementeerd met System.Security.Cryptography.AesGcm respectievelijk System.Security.Cryptography.AesCcm . Deze algoritmen zijn beide geverifieerde versleuteling met AEAD-algoritmen (Association Data).

De volgende code demonstreert het gebruik van AesGcm codering om willekeurige gegevens te versleutelen en te ontsleutelen.

using System;
using System.Linq;
using System.Security.Cryptography;

namespace whats_new
{
    public static class Cipher
    {
        public static void Run()
        {
            // key should be: pre-known, derived, or transported via another channel, such as RSA encryption
            byte[] key = new byte[16];
            RandomNumberGenerator.Fill(key);

            byte[] nonce = new byte[12];
            RandomNumberGenerator.Fill(nonce);

            // normally this would be your data
            byte[] dataToEncrypt = new byte[1234];
            byte[] associatedData = new byte[333];
            RandomNumberGenerator.Fill(dataToEncrypt);
            RandomNumberGenerator.Fill(associatedData);

            // these will be filled during the encryption
            byte[] tag = new byte[16];
            byte[] ciphertext = new byte[dataToEncrypt.Length];

            using (AesGcm aesGcm = new AesGcm(key))
            {
                aesGcm.Encrypt(nonce, dataToEncrypt, ciphertext, tag, associatedData);
            }

            // tag, nonce, ciphertext, associatedData should be sent to the other part

            byte[] decryptedData = new byte[ciphertext.Length];

            using (AesGcm aesGcm = new AesGcm(key))
            {
                aesGcm.Decrypt(nonce, ciphertext, tag, decryptedData, associatedData);
            }

            // do something with the data
            // this should always print that data is the same
            Console.WriteLine($"AES-GCM: Decrypted data is {(dataToEncrypt.SequenceEqual(decryptedData) ? "the same as" : "different than")} original data.");
        }
    }
}

Cryptografische sleutel importeren/exporteren

.NET Core 3.0 ondersteunt het importeren en exporteren van asymmetrische openbare en persoonlijke sleutels uit standaardindelingen. U hoeft geen X.509-certificaat te gebruiken.

Alle sleuteltypen, zoals RSA, DSA, ECDsa en ECDiffieHellman, ondersteunen de volgende indelingen:

  • Openbare sleutel

    • X.509 SubjectPublicKeyInfo
  • Persoonlijke sleutel

    • PKCS#8 PrivateKeyInfo
    • PKCS#8 EncryptedPrivateKeyInfo

RSA-sleutels ondersteunen ook:

  • Openbare sleutel

    • PKCS#1 RSAPublicKey
  • Persoonlijke sleutel

    • PKCS#1 RSAPrivateKey

De exportmethoden produceren binaire DER-gecodeerde gegevens en de importmethoden verwachten hetzelfde. Als een sleutel wordt opgeslagen in de tekstvriendelijke PEM-indeling, moet de aanroeper de inhoud base64 decoderen voordat een importmethode wordt aangeroepen.

using System;
using System.Security.Cryptography;

namespace whats_new
{
    public static class RSATest
    {
        public static void Run(string keyFile)
        {
            using var rsa = RSA.Create();

            byte[] keyBytes = System.IO.File.ReadAllBytes(keyFile);
            rsa.ImportRSAPrivateKey(keyBytes, out int bytesRead);

            Console.WriteLine($"Read {bytesRead} bytes, {keyBytes.Length - bytesRead} extra byte(s) in file.");
            RSAParameters rsaParameters = rsa.ExportParameters(true);
            Console.WriteLine(BitConverter.ToString(rsaParameters.D));
        }
    }
}

PKCS#8 bestanden kunnen worden geïnspecteerd met System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo en PFX/PKCS#12 bestanden kunnen worden geïnspecteerd met System.Security.Cryptography.Pkcs.Pkcs12Info. PFX-/PKCS#12-bestanden kunnen worden gemanipuleerd met System.Security.Cryptography.Pkcs.Pkcs12Builder.

API-wijzigingen in .NET Core 3.0

Bereiken en indexen

Het nieuwe System.Index type kan worden gebruikt voor indexering. U kunt er een maken op basis van een int waarde die vanaf het begin wordt geteld of met een voorvoegseloperator ^ (C#) die vanaf het einde telt:

Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

Er is ook het System.Range type, dat bestaat uit twee Index waarden, één voor het begin en een voor het einde, en kan worden geschreven met een x..y bereikexpressie (C#). Vervolgens kunt u indexeren met een Range, waarmee een segment wordt geproduceerd:

var slice = a[i1..i2]; // { 3, 4, 5 }

Zie de zelfstudie bereiken en indexen voor meer informatie.

Asynchrone streams

Het IAsyncEnumerable<T> type is een nieuwe asynchrone versie van IEnumerable<T>. Met de taal kunt u await foreach IAsyncEnumerable<T> hun elementen gebruiken en gebruiken yield return om elementen te produceren.

In het volgende voorbeeld ziet u zowel productie als verbruik van asynchrone streams. De foreach instructie is asynchroon en zelf gebruikt yield return om een asynchrone stroom te produceren voor bellers. Dit patroon (met behulp van yield return) is het aanbevolen model voor het produceren van asynchrone streams.

async IAsyncEnumerable<int> GetBigResultsAsync()
{
    await foreach (var result in GetResultsAsync())
    {
        if (result > 20) yield return result;
    }
}

Naast het kunnenawait foreach, kunt u ook asynchrone iterators maken, bijvoorbeeld een iterator die een IAsyncEnumerable/IAsyncEnumerator iterator retourneert die u zowel als yield in kunt await gebruiken. Voor objecten die moeten worden verwijderd, kunt u gebruiken IAsyncDisposable, welke verschillende BCL-typen implementeren, zoals Stream en Timer.

Zie de zelfstudie asynchrone streams voor meer informatie.

IEEE-drijvende komma

Drijvendekomma-API's worden bijgewerkt om te voldoen aan de IEEE 754-2008-revisie. Het doel van deze wijzigingen is om alle vereiste bewerkingen beschikbaar te maken en ervoor te zorgen dat ze gedragsmatig compatibel zijn met de IEEE-specificatie. Zie het blogbericht Drijvendekomma parseren en opmaak in .NET Core 3.0 voor meer informatie over verbeteringen in drijvende komma.

Oplossingen voor parseren en opmaken zijn onder andere:

  • Correct parseren en afronden van invoer van elke lengte.
  • Parseren en negatieve nul opmaken.
  • Correct parseren Infinity en NaN door een niet-hoofdlettergevoelige controle uit te voeren en een optionele voorafgaande + indien van toepassing toe te staan.

Nieuwe System.Math API's zijn onder andere:

  • BitIncrement(Double) en BitDecrement(Double)
    Komt overeen met de nextUp en nextDown IEEE-bewerkingen. Ze retourneren het kleinste drijvendekommagetal dat groter of kleiner is dan de invoer (respectievelijk). Bijvoorbeeld: Math.BitIncrement(0.0) retourneert double.Epsilon.

  • MaxMagnitude(Double, Double) en MinMagnitude(Double, Double)
    Komt overeen met de maxNumMag en minNumMag IEEE-bewerkingen, ze retourneren de waarde die groter of kleiner is in grootte van de twee invoerwaarden (respectievelijk). Bijvoorbeeld: Math.MaxMagnitude(2.0, -3.0) retourneert -3.0.

  • ILogB(Double)
    Komt overeen met de logB IEEE-bewerking die een integrale waarde retourneert. Het retourneert het integrale base-2-logboek van de invoerparameter. Deze methode is in feite hetzelfde als floor(log2(x)), maar wordt uitgevoerd met een minimale afrondingsfout.

  • ScaleB(Double, Int32)
    Komt overeen met de scaleB IEEE-bewerking waarbij een integrale waarde wordt gebruikt. Deze retourneert effectief x * pow(2, n), maar wordt uitgevoerd met een minimale afrondingsfout.

  • Log2(Double)
    Komt overeen met de log2 IEEE-bewerking en retourneert de logaritme base-2. De afrondingsfout wordt geminimaliseerd.

  • FusedMultiplyAdd(Double, Double, Double)
    Komt overeen met de fma IEEE-bewerking en voert een samenvoeging van vermenigvuldiging uit. Dat wil gezegd, het doet (x * y) + z als één bewerking, waardoor de afrondingsfout wordt geminimaliseerd. Een voorbeeld is FusedMultiplyAdd(1e308, 2.0, -1e308), dat retourneert 1e308. De reguliere (1e308 * 2.0) - 1e308 retourneert double.PositiveInfinity.

  • CopySign(Double, Double)
    Komt overeen met de copySign IEEE-bewerking, het retourneert de waarde van x, maar met het teken van y.

.NET Platformafhankelijke intrinsieken

API's zijn toegevoegd die toegang bieden tot bepaalde prestatiegerichte CPU-instructies, zoals de SIMD - of Bit Manipulatie-instructiesets . Deze instructies kunnen helpen bij het realiseren van aanzienlijke prestatieverbeteringen in bepaalde scenario's, zoals het efficiënt verwerken van gegevens parallel.

Waar van toepassing zijn de .NET-bibliotheken begonnen met het gebruik van deze instructies om de prestaties te verbeteren.

Zie .NET Platformafhankelijke intrinsieken voor meer informatie.

Verbeterde .NET Core-versie-API's

Vanaf .NET Core 3.0 retourneren de versie-API's van .NET Core nu de informatie die u verwacht. Voorbeeld:

System.Console.WriteLine($"Environment.Version: {System.Environment.Version}");

// Old result
//   Environment.Version: 4.0.30319.42000
//
// New result
//   Environment.Version: 3.0.0
System.Console.WriteLine($"RuntimeInformation.FrameworkDescription: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");

// Old result
//   RuntimeInformation.FrameworkDescription: .NET Core 4.6.27415.71
//
// New result (notice the value includes any preview release information)
//   RuntimeInformation.FrameworkDescription: .NET Core 3.0.0-preview4-27615-11

Waarschuwing

Wijziging die fouten veroorzaken. Dit is technisch gezien een belangrijke wijziging omdat het versiebeheerschema is gewijzigd.

Snelle ingebouwde JSON-ondersteuning

.NET-gebruikers hebben grotendeels vertrouwd op Newtonsoft.Json en andere populaire JSON-bibliotheken, die nog steeds goede keuzes blijven. Newtonsoft.Json maakt gebruik van .NET-tekenreeksen als het basisgegevenstype, dat UTF-16 onder de kap is.

De nieuwe ingebouwde JSON-ondersteuning is high-performance, lage toewijzing en werkt met UTF-8 gecodeerde JSON-tekst. Zie de volgende artikelen voor meer informatie over de System.Text.Json naamruimte en typen:

Ondersteuning voor HTTP/2

Het System.Net.Http.HttpClient type ondersteunt het HTTP/2-protocol. Als HTTP/2 is ingeschakeld, wordt de VERSIE van het HTTP-protocol onderhandeld via TLS/ALPN en WORDT HTTP/2 gebruikt als de server ervoor kiest deze te gebruiken.

Het standaardprotocol blijft HTTP/1.1, maar HTTP/2 kan op twee verschillende manieren worden ingeschakeld. Eerst kunt u het HTTP-aanvraagbericht instellen om HTTP/2 te gebruiken:

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);

Ten tweede kunt u het gebruik van HTTP/2 standaard wijzigen HttpClient :

var client = new HttpClient()
{
    BaseAddress = new Uri("https://localhost:5001"),
    DefaultRequestVersion = new Version(2, 0)
};

// HTTP/2 is default
using (var response = await client.GetAsync("/"))
    Console.WriteLine(response.Content);

Vaak wanneer u een toepassing ontwikkelt, wilt u een niet-versleutelde verbinding gebruiken. Als u weet dat het doeleindpunt HTTP/2 gebruikt, kunt u niet-versleutelde verbindingen voor HTTP/2 inschakelen. U kunt deze inschakelen door de DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT omgevingsvariabele in te 1 stellen op of in te schakelen in de app-context:

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

Volgende stappen