Co nowego w programie .NET Core 3.0

W tym artykule opisano nowości w programie .NET Core 3.0. Jednym z największych ulepszeń jest obsługa aplikacji klasycznych systemu Windows (tylko system Windows). Korzystając ze składnika .NET Core 3.0 SDK dla systemu Windows Desktop, można przenosić aplikacje Windows Forms i Windows Presentation Foundation (WPF). Aby było jasne, składnik pulpitu systemu Windows jest obsługiwany tylko i dołączony do systemu Windows. Aby uzyskać więcej informacji, zobacz sekcję pulpitu systemu Windows w dalszej części tego artykułu.

Platforma .NET Core 3.0 dodaje obsługę języka C# 8.0. Zdecydowanie zaleca się używanie programu Visual Studio 2019 w wersji 16.3 lub nowszej, Visual Studio dla komputerów Mac 8.3 lub nowszej albo programu Visual Studio Code z najnowszym rozszerzeniem języka C#.

Pobierz i rozpocznij pracę z platformą .NET Core 3.0 w systemie Windows, macOS lub Linux.

Aby uzyskać więcej informacji na temat wydania, zobacz ogłoszenie platformy .NET Core 3.0.

Program .NET Core 3.0 RC 1 został uznany za gotowy do produkcji przez firmę Microsoft i był w pełni obsługiwany. Jeśli używasz wersji zapoznawczej, musisz przejść do wersji RTM, aby kontynuować obsługę.

Ulepszenia języka C# 8.0

Język C# 8.0 jest również częścią tej wersji, która obejmuje funkcję typów odwołań dopuszczających wartość null, strumienie asynchroniczne i inne wzorce. Aby uzyskać więcej informacji na temat funkcji języka C# 8.0, zobacz Co nowego w języku C# 8.0.

Samouczki związane z funkcjami języka C# 8.0:

Dodano ulepszenia języka w celu obsługi następujących funkcji interfejsu API opisanych poniżej:

.NET Standard 2.1

Platforma .NET Core 3.0 implementuje platformę .NET Standard 2.1. Jednak domyślny dotnet new classlib szablon generuje projekt, który nadal jest przeznaczony dla platformy .NET Standard 2.0. Aby użyć platformy .NET Standard 2.1, zmodyfikuj TargetFramework plik projektu i zmień właściwość na netstandard2.1:

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

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

</Project>

Jeśli używasz programu Visual Studio, potrzebujesz programu Visual Studio 2019, ponieważ program Visual Studio 2017 nie obsługuje programu .NET Standard 2.1 ani .NET Core 3.0.

Kompilowanie/wdrażanie

Domyślne pliki wykonywalne

Platforma .NET Core domyślnie kompiluje pliki wykonywalne zależne od platformy . To zachowanie jest nowe w przypadku aplikacji korzystających z globalnie zainstalowanej wersji platformy .NET Core. Wcześniej tylko wdrożenia samodzielne tworzyły plik wykonywalny.

Podczas dotnet build lub dotnet publishtworzony jest plik wykonywalny (znany jako appHost), który jest zgodny ze środowiskiem i platformą używanego zestawu SDK. Możesz oczekiwać tych samych elementów przy użyciu tych plików wykonywalnych, co inne natywne pliki wykonywalne, takie jak:

  • Możesz kliknąć dwukrotnie plik wykonywalny.
  • Aplikację można uruchomić bezpośrednio z poziomu wiersza polecenia, takiego jak myapp.exe w systemie Windows i ./myapp w systemach Linux i macOS.

Host aplikacji systemu macOS i notaryzacja

Tylko system macOS

Począwszy od notarizowanego zestawu .NET Core SDK 3.0 dla systemu macOS, ustawienie tworzenia domyślnego pliku wykonywalnego (znanego jako appHost) jest domyślnie wyłączone. Aby uzyskać więcej informacji, zobacz notarization and the impact on .NET Core downloads and projects (Notarization) i wpływ na pobieranie i projekty platformy .NET Core.

Po włączeniu ustawienia appHost platforma .NET Core generuje natywny plik wykonywalny Mach-O podczas kompilowanie lub publikowanie. Aplikacja jest uruchamiana w kontekście elementu appHost, gdy jest uruchamiana z kodu źródłowego za dotnet run pomocą polecenia lub uruchamiając plik wykonywalny Mach-O bezpośrednio.

Bez elementu appHost jedynym sposobem, w jaki użytkownik może uruchomić aplikację zależną od platformy, jest polecenie dotnet <filename.dll> . Host appHost jest zawsze tworzony podczas samodzielnego publikowania aplikacji.

Możesz skonfigurować host appHost na poziomie projektu lub przełączyć element appHost dla określonego dotnet polecenia za pomocą parametru -p:UseAppHost :

  • Plik projektu

    <PropertyGroup>
      <UseAppHost>true</UseAppHost>
    </PropertyGroup>
    
  • Parametr wiersza polecenia

    dotnet run -p:UseAppHost=true
    

Aby uzyskać więcej informacji na temat UseAppHost ustawienia, zobacz Właściwości programu MSBuild dla zestawu Microsoft.NET.Sdk.

Pliki wykonywalne z jednym plikiem

Polecenie dotnet publish obsługuje pakowanie aplikacji do pliku wykonywalnego pojedynczego pliku specyficznego dla platformy. Plik wykonywalny jest wyodrębniany samodzielnie i zawiera wszystkie zależności (w tym natywne), które są wymagane do uruchomienia aplikacji. Po pierwszym uruchomieniu aplikacji aplikacja zostanie wyodrębniona do katalogu na podstawie nazwy aplikacji i identyfikatora kompilacji. Uruchamianie jest szybsze po ponownym uruchomieniu aplikacji. Aplikacja nie musi wyodrębniać się po raz drugi, chyba że została użyta nowa wersja.

Aby opublikować plik wykonywalny z jednym plikiem, ustaw element PublishSingleFile w projekcie lub w wierszu polecenia za dotnet publish pomocą polecenia :

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

— lub —

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

Aby uzyskać więcej informacji na temat publikowania w jednym pliku, zobacz dokument projektowy programu bundler z jednym plikiem.

Przycinanie zestawów

Zestaw .NET Core 3.0 SDK jest dostarczany z narzędziem, które może zmniejszyć rozmiar aplikacji, analizując il i przycinając nieużywane zestawy.

Aplikacje samodzielne obejmują wszystkie elementy potrzebne do uruchomienia kodu bez konieczności instalowania platformy .NET na komputerze hosta. Jednak wiele razy aplikacja wymaga tylko małego podzbioru platformy do działania, a inne nieużywane biblioteki można usunąć.

Platforma .NET Core zawiera teraz ustawienie, które będzie używać narzędzia IL Trimmer do skanowania il aplikacji. To narzędzie wykrywa wymagany kod, a następnie przycina nieużywane biblioteki. To narzędzie może znacznie zmniejszyć rozmiar wdrożenia niektórych aplikacji.

Aby włączyć to narzędzie, dodaj <PublishTrimmed> ustawienie w projekcie i opublikuj samodzielną aplikację:

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

Na przykład podstawowy szablon projektu konsoli "hello world", który jest uwzględniony po opublikowaniu, osiąga około 70 MB rozmiaru. Za pomocą polecenia <PublishTrimmed>rozmiar ten jest mniejszy do około 30 MB.

Ważne jest, aby wziąć pod uwagę, że aplikacje lub struktury (w tym ASP.NET Core i WPF), które używają odbicia lub powiązanych funkcji dynamicznych, często będą przerywane po przycinaniu. Ten podział występuje, ponieważ trimmer nie wie o tym zachowaniu dynamicznym i nie może określić, które typy platform są wymagane do odbicia. Narzędzie il trimmer można skonfigurować tak, aby pamiętać o tym scenariuszu.

Przede wszystkim pamiętaj, aby przetestować aplikację po przycinaniu.

Aby uzyskać więcej informacji na temat narzędzia IL Trimmer, zobacz dokumentację lub odwiedź repozytorium mono/konsolidatora.

Kompilacja warstwowa

Kompilacja warstwowa (TC) jest domyślnie włączona w programie .NET Core 3.0. Ta funkcja umożliwia środowisku uruchomieniowemu bardziej adaptacyjne korzystanie z kompilatora just in time (JIT) w celu uzyskania lepszej wydajności.

Główną zaletą kompilacji warstwowej jest zapewnienie dwóch sposobów jitting metod: w niższej jakości, ale szybciej warstwy lub wyższej jakości, ale wolniejszej warstwy. Jakość odnosi się do tego, jak dobrze jest zoptymalizowana metoda. TC pomaga zwiększyć wydajność aplikacji, ponieważ przechodzi przez różne etapy wykonywania, od uruchamiania przez stały stan. Gdy kompilacja warstwowa jest wyłączona, każda metoda jest kompilowana w jeden sposób, który jest stronniczy do stałej wydajności nad wydajnością uruchamiania.

Po włączeniu TC następujące zachowanie ma zastosowanie do kompilacji metody podczas uruchamiania aplikacji:

  • Jeśli metoda ma wcześniej skompilowany kod lub ReadyToRun, używany jest wstępnie wygenerowany kod.
  • W przeciwnym razie metoda jest wyśmiewane. Zazwyczaj te metody są rodzajami ogólnymi dla typów wartości.
    • Szybki dostęp JIT szybciej generuje kod niższej jakości (lub mniej zoptymalizowany). W programie .NET Core 3.0 szybki dostęp JIT jest domyślnie włączony dla metod, które nie zawierają pętli i są preferowane podczas uruchamiania.
    • W pełni optymalizowanie trybu JIT generuje kod o wyższej jakości (lub bardziej zoptymalizowany) wolniej. W przypadku metod, w których nie będzie używany szybki dostęp JIT (na przykład jeśli metoda jest przypisywana za pomocą MethodImplOptions.AggressiveOptimizationmetody ), jest używana w pełni optymalizowanie trybu JIT.

W przypadku często nazywanych metodami kompilator just in time ostatecznie tworzy w pełni zoptymalizowany kod w tle. Zoptymalizowany kod zastępuje następnie wstępnie skompilowany kod dla tej metody.

Kod generowany przez szybki dostęp JIT może działać wolniej, przydzielić więcej pamięci lub użyć więcej miejsca na stosie. Jeśli występują problemy, możesz wyłączyć szybki dostęp JIT przy użyciu tej właściwości MSBuild w pliku projektu:

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

Aby całkowicie wyłączyć TC, użyj tej właściwości MSBuild w pliku projektu:

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

Napiwek

W przypadku zmiany tych ustawień w pliku projektu może być konieczne wykonanie czystej kompilacji, aby nowe ustawienia zostały odzwierciedlone (usuń obj katalogi i bin i ponownie skompiluj).

Aby uzyskać więcej informacji na temat konfigurowania kompilacji w czasie wykonywania, zobacz Opcje konfiguracji środowiska uruchomieniowego na potrzeby kompilacji.

Obrazy ReadyToRun

Czas uruchamiania aplikacji .NET Core można poprawić, kompilując zestawy aplikacji jako format ReadyToRun (R2R). R2R jest formą kompilacji przed czasem (AOT).

Pliki binarne R2R zwiększają wydajność uruchamiania, zmniejszając ilość pracy kompilatora just in time (JIT), który musi wykonywać podczas ładowania aplikacji. Pliki binarne zawierają podobny kod macierzysty w porównaniu z elementem JIT, który mógłby wygenerować. Jednak pliki binarne R2R są większe, ponieważ zawierają zarówno kod języka pośredniego (IL), który jest nadal potrzebny w niektórych scenariuszach, oraz natywną wersję tego samego kodu. R2R jest dostępny tylko w przypadku publikowania samodzielnej aplikacji przeznaczonej dla określonych środowisk uruchomieniowych (RID), takich jak Linux x64 lub Windows x64.

Aby skompilować projekt jako ReadyToRun, wykonaj następujące czynności:

  1. <PublishReadyToRun> Dodaj ustawienie do projektu:

    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
  2. Publikowanie aplikacji samodzielnej. Na przykład to polecenie tworzy samodzielną aplikację dla 64-bitowej wersji systemu Windows:

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

Ograniczenia międzyplatformowe/architektury

Kompilator ReadyToRun nie obsługuje obecnie krzyżowego określania wartości docelowych. Musisz skompilować dane docelowe. Jeśli na przykład chcesz używać obrazów R2R dla systemu Windows x64, musisz uruchomić polecenie publish w tym środowisku.

Wyjątki od określania wartości krzyżowych:

  • System Windows x64 może służyć do kompilowania obrazów systemu Windows Arm32, Arm64 i x86.
  • Windows x86 może służyć do kompilowania obrazów systemu Windows Arm32.
  • System Linux x64 może służyć do kompilowania obrazów arm32 i Arm64 z systemem Linux.

Aby uzyskać więcej informacji, zobacz Gotowość do uruchomienia.

Środowisko uruchomieniowe/zestaw SDK

Wycofywanie środowiska uruchomieniowego wersji głównej

Platforma .NET Core 3.0 wprowadza funkcję zgody, która umożliwia aplikacji przekazywanie do najnowszej wersji głównej platformy .NET Core. Ponadto dodano nowe ustawienie w celu kontrolowania sposobu przesyłania dalej do aplikacji. Można to skonfigurować na następujące sposoby:

  • Właściwość pliku projektu: RollForward
  • Właściwość pliku konfiguracji środowiska uruchomieniowego: rollForward
  • Zmienna środowiskowa: DOTNET_ROLL_FORWARD
  • Argument wiersza polecenia: --roll-forward

Należy określić jedną z następujących wartości. Jeśli ustawienie zostanie pominięte, wartość pomocnicza jest wartością domyślną.

  • Najnowszapatch
    Przerzuć do najwyższej wersji poprawki. Spowoduje to wyłączenie wycofywania wersji pomocniczej.
  • Nieistotne
    Jeśli zażądano wersji pomocniczej, przejdź do najniższej wyższej wersji pomocniczej. Jeśli żądana wersja pomocnicza jest obecna, zostaną użyte zasady LatestPatch .
  • Istotne
    Przejdź do najniższej wyższej wersji głównej i najniższej wersji pomocniczej, jeśli zażądano wersji głównej. Jeśli żądana wersja główna jest obecna, zostaną użyte zasady pomocnicze .
  • LatestMinor
    Przerzuć do najwyższej wersji pomocniczej, nawet jeśli zażądano wersji pomocniczej. Przeznaczony dla scenariuszy hostingu składników.
  • LatestMajor
    Przerzuć do najwyższej wersji głównej i najwyższej wersji pomocniczej, nawet jeśli zażądano wersji głównej. Przeznaczony dla scenariuszy hostingu składników.
  • Wyłącz
    Nie przerzuć się do przodu. Wiązanie tylko z określoną wersją. Te zasady nie są zalecane do użytku ogólnego, ponieważ wyłącza możliwość przekazywania do najnowszych poprawek. Ta wartość jest zalecana tylko do testowania.

Oprócz ustawienia Wyłącz wszystkie ustawienia będą używać najwyższej dostępnej wersji poprawki.

Domyślnie, jeśli żądana wersja (określona w .runtimeconfig.json dla aplikacji) jest wersją wydania, tylko wersje wersji są brane pod uwagę do wycofania. Wszystkie wersje wstępne są ignorowane. Jeśli wersja wersji nie jest zgodna, należy wziąć pod uwagę wersje wstępne. To zachowanie można zmienić przez ustawienie DOTNET_ROLL_FORWARD_TO_PRERELEASE=1, w którym przypadku wszystkie wersje są zawsze brane pod uwagę.

Tworzenie zależności kopii

Polecenie dotnet build kopiuje teraz zależności NuGet dla aplikacji z pamięci podręcznej NuGet do folderu danych wyjściowych kompilacji. Wcześniej zależności były kopiowane tylko w ramach elementu dotnet publish.

Istnieją pewne operacje, takie jak przycinanie i publikowanie stron razor, które nadal będą wymagały publikowania.

Narzędzia lokalne

Platforma .NET Core 3.0 wprowadza narzędzia lokalne. Narzędzia lokalne są podobne do narzędzi globalnych, ale są skojarzone z określoną lokalizacją na dysku. Narzędzia lokalne nie są dostępne globalnie i są dystrybuowane jako pakiety NuGet.

Narzędzia lokalne bazują na nazwie dotnet-tools.json pliku manifestu w bieżącym katalogu. Ten plik manifestu definiuje narzędzia, które mają być dostępne w tym folderze i poniżej. Możesz rozpowszechnić plik manifestu przy użyciu kodu, aby upewnić się, że każdy, kto współpracuje z kodem, może przywrócić i użyć tych samych narzędzi.

W przypadku narzędzi globalnych i lokalnych wymagana jest zgodna wersja środowiska uruchomieniowego. Wiele narzędzi obecnie w środowisku docelowym platformy .NET Core Runtime 2.1 NuGet.org. Aby zainstalować te narzędzia globalnie lub lokalnie, nadal trzeba zainstalować środowisko uruchomieniowe platformy NET Core 2.1.

Nowe opcje global.json

Plik global.json zawiera nowe opcje, które zapewniają większą elastyczność podczas próby zdefiniowania, która wersja zestawu .NET Core SDK jest używana. Nowe opcje to:

  • allowPrerelease: wskazuje, czy program rozpoznawania zestawu SDK powinien uwzględniać wersje wstępne podczas wybierania wersji zestawu SDK do użycia.
  • rollForward: wskazuje zasady wycofywania, które mają być używane podczas wybierania wersji zestawu SDK, jako rezerwowego, gdy brakuje określonej wersji zestawu SDK lub jako dyrektywa w celu korzystania z nowszej wersji.

Aby uzyskać więcej informacji na temat zmian, w tym wartości domyślnych, obsługiwanych wartości i nowych reguł dopasowania, zobacz global.json omówienie.

Mniejsze rozmiary sterty odzyskiwania pamięci

Domyślny rozmiar sterty modułu odśmiecniania pamięci został zmniejszony, co powoduje zmniejszenie użycia platformy .NET Core przy użyciu mniejszej ilości pamięci. Ta zmiana lepiej pasuje do budżetu alokacji generacji 0 z nowoczesnymi rozmiarami pamięci podręcznej procesora.

Obsługa dużej strony odzyskiwania pamięci

Duże strony (nazywane również ogromnymi stronami w systemie Linux) to funkcja, w której system operacyjny może ustanowić regiony pamięci większe niż rozmiar strony natywnej (często 4K), aby zwiększyć wydajność aplikacji żądającej tych dużych stron.

Moduł zbierający elementy bezużyteczne można teraz skonfigurować przy użyciu ustawienia GCLargePages jako funkcji zgody na przydzielanie dużych stron w systemie Windows.

Windows Desktop i COM

Instalator windows zestawu .NET Core SDK

Instalator MSI dla systemu Windows zmienił się począwszy od platformy .NET Core 3.0. Instalatory zestawu SDK uaktualnią teraz wersje zestawu SDK dla pasmów funkcji. Pasma funkcji są definiowane w setkach grup w sekcji poprawki numeru wersji. Na przykład 3.0.101 i 3.0.201 to wersje w dwóch różnych przedziałach funkcji, podczas gdy 3.0.101 i 3.0.199 jest w tym samym zespole funkcji. A gdy zestaw .NET Core SDK 3.0.Zainstalowano 101 zestaw .NET Core SDK 3.0.100 zostanie usunięty z maszyny, jeśli istnieje. Gdy zestaw .NET Core SDK 3.0.Program 200 jest zainstalowany na tej samej maszynie, na platformie .NET Core SDK 3.0.101 nie zostanie usunięty.

Aby uzyskać więcej informacji na temat przechowywania wersji, zobacz Overview of how .NET Core is versioned (Omówienie sposobu przechowywania wersji platformy .NET Core).

Pulpit systemu Windows

Platforma .NET Core 3.0 obsługuje aplikacje klasyczne systemu Windows przy użyciu programów Windows Presentation Foundation (WPF) i Windows Forms. Te struktury obsługują również używanie nowoczesnych kontrolek i stylu Fluent z biblioteki XAML interfejsu użytkownika systemu Windows (WinUI) za pośrednictwem wysp XAML.

Składnik pulpitu systemu Windows jest częścią zestawu SDK platformy .NET Core 3.0 systemu Windows.

Nową aplikację WPF lub Windows Forms można utworzyć przy użyciu następujących dotnet poleceń:

dotnet new wpf
dotnet new winforms

Program Visual Studio 2019 dodaje nowe szablony projektów dla platformy .NET Core 3.0 Windows Forms i WPF.

Aby uzyskać więcej informacji na temat przenoszenia istniejącej aplikacji .NET Framework, zobacz Port WPF projects and Port Windows Forms projects (Port WPF projects and Port Windows Forms projects).

Funkcja WinForms o wysokiej rozdzielczości DPI

Aplikacje .NET Core Windows Forms mogą ustawiać tryb wysokiej rozdzielczości DPI za pomocą polecenia Application.SetHighDpiMode(HighDpiMode). Metoda SetHighDpiMode ustawia odpowiedni tryb wysokiej dpi, chyba że ustawienie zostało ustawione za pomocą innych środków, takich jak App.Manifest lub P/Invoke przed Application.Run.

Możliwe highDpiMode wartości wyrażone przez wyliczenie System.Windows.Forms.HighDpiMode to:

  • DpiUnaware
  • SystemAware
  • PerMonitor
  • PerMonitorV2
  • DpiUnawareGdiScaled

Aby uzyskać więcej informacji na temat trybów wysokiej rozdzielczości DPI, zobacz High DPI Desktop Application Development on Windows (Tworzenie aplikacji klasycznych o wysokiej rozdzielczości DPI w systemie Windows).

Tworzenie składników COM

W systemie Windows można teraz tworzyć składniki zarządzane z możliwością wywoływania modelu COM. Ta funkcja ma kluczowe znaczenie dla używania platformy .NET Core z modelami dodatków COM, a także zapewnia parzystość z programem .NET Framework.

W przeciwieństwie do programu .NET Framework, w którym mscoree.dll był używany jako serwer COM, platforma .NET Core doda natywną bibliotekę dll uruchamiania do katalogu bin podczas kompilowania składnika COM.

Aby zapoznać się z przykładem tworzenia składnika COM i korzystania z niego, zobacz pokaz COM.

Międzyoperacyjna z systemem Windows Native

System Windows oferuje bogaty natywny interfejs API w postaci prostych interfejsów API języka C, MODELU COM i WinRT. Chociaż platforma .NET Core obsługuje P/Invoke, platforma .NET Core 3.0 dodaje możliwość współtworzenia interfejsów API COM i aktywowania interfejsów API WinRT. Aby zapoznać się z przykładem kodu, zobacz Pokaz programu Excel.

Wdrażanie MSIX

MSIX to nowy format pakietu aplikacji systemu Windows. Może służyć do wdrażania aplikacji klasycznych platformy .NET Core 3.0 w systemie Windows 10.

Projekt tworzenia pakietów aplikacji systemu Windows dostępny w programie Visual Studio 2019 umożliwia tworzenie pakietów MSIX z samodzielnymi aplikacjami platformy .NET Core.

Plik projektu .NET Core musi określać obsługiwane środowiska uruchomieniowe we <RuntimeIdentifiers> właściwości :

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

Ulepszenia systemu Linux

SerialPort dla systemu Linux

Platforma .NET Core 3.0 zapewnia podstawową obsługę System.IO.Ports.SerialPort w systemie Linux.

Wcześniej platforma .NET Core obsługiwana tylko w SerialPort systemie Windows.

Aby uzyskać więcej informacji na temat ograniczonej obsługi portu szeregowego w systemie Linux, zobacz Problem z usługą GitHub #33146.

Limity pamięci platformy Docker i grupy cgroup

Uruchamianie platformy .NET Core 3.0 w systemie Linux z platformą Docker działa lepiej z limitami pamięci cgroup. Uruchamianie kontenera platformy Docker z limitami pamięci, takimi jak z docker run -m, zmienia sposób działania platformy .NET Core.

  • Domyślny rozmiar sterty modułu odśmieceń pamięci (GC): maksymalnie 20 mb lub 75% limitu pamięci w kontenerze.
  • Jawny rozmiar można ustawić jako bezwzględną liczbę lub wartość procentową limitu cgroup.
  • Minimalny rozmiar segmentu zarezerwowanego na stertę GC wynosi 16 mb. Ten rozmiar zmniejsza liczbę sterty tworzonych na maszynach.

Obsługa funkcji GPIO dla urządzenia Raspberry Pi

Dwa pakiety zostały wydane dla nuGet, których można użyć do programowania GPIO:

Pakiety GPIO obejmują interfejsy API dla urządzeń GPIO, SPI, I2C i PWM . Pakiet powiązań IoT zawiera powiązania urządzeń. Aby uzyskać więcej informacji, zobacz repozytorium GitHub urządzeń.

Obsługa systemu Linux arm64

Platforma .NET Core 3.0 dodaje obsługę architektury Arm64 dla systemu Linux. Podstawowy przypadek użycia dla usługi Arm64 jest obecnie w scenariuszach IoT. Aby uzyskać więcej informacji, zobacz Stan arm64 platformy .NET Core.

Obrazy platformy Docker dla platformy .NET Core na platformie Arm64 są dostępne dla systemów Alpine, Debian i Ubuntu.

Uwaga

Obsługa systemów operacyjnych macOS Arm64 (lub "Apple Silicon") i Windows Arm64 została później dodana na platformie .NET 6.

Zabezpieczenia

TLS 1.3 i OpenSSL 1.1.1 w systemie Linux

Platforma .NET Core korzysta teraz z obsługi protokołu TLS 1.3 w programie OpenSSL 1.1.1, gdy jest dostępna w danym środowisku. W przypadku protokołu TLS 1.3:

  • Połączenie czasy są poprawiane dzięki zmniejszeniu liczby rund wymaganych między klientem a serwerem.
  • Ulepszone zabezpieczenia ze względu na usunięcie różnych przestarzałych i niezabezpieczonych algorytmów kryptograficznych.

Jeśli jest dostępna, platforma .NET Core 3.0 używa biblioteki OpenSSL 1.1.1, OpenSSL 1.1.0 lub OpenSSL 1.0.2 w systemie Linux. Gdy program OpenSSL 1.1.1 jest dostępny, oba System.Net.Security.SslStreamSystem.Net.Http.HttpClient typy będą używać protokołu TLS 1.3 (przy założeniu, że klient i serwer obsługują protokół TLS 1.3).

W poniższym przykładzie języka C# 8.0 pokazano platformę .NET Core 3.0 w systemie Ubuntu 18.10 łączącą się z :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}");
        }
    }
}

Szyfry kryptograficzne

Platforma .NET Core 3.0 dodaje obsługę szyfrów AES-GCM i AES-CCM , zaimplementowanych odpowiednio za pomocą System.Security.Cryptography.AesGcm i System.Security.Cryptography.AesCcm . Te algorytmy są algorytmami szyfrowania uwierzytelnionego przy użyciu danych skojarzenia (AEAD).

Poniższy kod demonstruje użycie AesGcm szyfrowania do szyfrowania i odszyfrowywania losowych danych.

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.");
        }
    }
}

Importowanie/eksportowanie kluczy kryptograficznych

Platforma .NET Core 3.0 obsługuje importowanie i eksportowanie asymetrycznych kluczy publicznych i prywatnych ze standardowych formatów. Nie musisz używać certyfikatu X.509.

Wszystkie typy kluczy, takie jak RSA, DSA, ECDsa i ECDiffieHellman, obsługują następujące formaty:

  • Klucz publiczny

    • X.509 SubjectPublicKeyInfo
  • Klucz prywatny

    • PKCS#8 PrivateKeyInfo
    • PKCS#8 EncryptedPrivateKeyInfo

Klucze RSA obsługują również następujące elementy:

  • Klucz publiczny

    • PKCS#1 RSAPublicKey
  • Klucz prywatny

    • PKCS#1 RSAPrivateKey

Metody eksportu generują dane binarne zakodowane w formacie DER, a metody importu oczekują tego samego. Jeśli klucz jest przechowywany w formacie PEM przyjazny dla tekstu, obiekt wywołujący będzie musiał zdekodować zawartość w formacie base64 przed wywołaniem metody importu.

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

Pliki PKCS#8 można sprawdzić, System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo a pliki PFX/PKCS#12 można sprawdzić za pomocą System.Security.Cryptography.Pkcs.Pkcs12Infopolecenia . Pliki PFX/PKCS#12 można manipulować za pomocą polecenia System.Security.Cryptography.Pkcs.Pkcs12Builder.

Zmiany interfejsu API platformy .NET Core 3.0

Zakresy i indeksy

System.Index Nowy typ może służyć do indeksowania. Możesz utworzyć jedną z wartości int zliczanej od początku lub z operatorem prefiksu ^ (C#), który zlicza się od końca:

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"

Istnieje również System.Range typ, który składa się z dwóch Index wartości, jeden dla początku i jeden dla końca, i można go zapisać za pomocą x..y wyrażenia zakresu (C#). Następnie można indeksować za pomocą elementu Range, który generuje wycinek:

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

Aby uzyskać więcej informacji, zobacz samouczek dotyczący zakresów i indeksów.

Strumienie asynchroniczne

Typ IAsyncEnumerable<T> jest nową asynchroniczną wersją programu IEnumerable<T>. Język umożliwia await foreachIAsyncEnumerable<T> korzystanie z ich elementów i używanie yield return ich do tworzenia elementów.

W poniższym przykładzie pokazano zarówno produkcję, jak i zużycie strumieni asynchronicznych. Instrukcja foreach jest asynchronizna i sama używa yield return jej do tworzenia strumienia asynchronicznego dla osób wywołujących. Ten wzorzec (przy użyciu yield returnmetody ) jest zalecanym modelem do tworzenia strumieni asynchronicznych.

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

Oprócz możliwości await foreachmożna również utworzyć iteratory asynchroniczne, na przykład iterator, który zwraca IAsyncEnumerable/IAsyncEnumerator wartość , którą można wykonać zarówno await , jak i yield w. W przypadku obiektów, które należy usunąć, można użyć polecenia IAsyncDisposable, które są implementowane różne typy BCL, takie jak Stream i Timer.

Aby uzyskać więcej informacji, zobacz samouczek dotyczący strumieni asynchronicznych.

IEEE zmiennoprzecinkowa

Interfejsy API zmiennoprzecinkowe są aktualizowane w celu zachowania zgodności z poprawką IEEE 754-2008. Celem tych zmian jest uwidocznienie wszystkich wymaganych operacji i upewnienie się, że są one behawioralnie zgodne ze specyfikacją IEEE. Aby uzyskać więcej informacji na temat ulepszeń zmiennoprzecinkowych, zobacz wpis w blogu Dotyczący analizowania i formatowania zmiennoprzecinkowego w programie .NET Core 3.0 .

Poprawki analizowania i formatowania obejmują:

  • Poprawnie analizuje i zaokrągla dane wejściowe o dowolnej długości.
  • Poprawnie przeanalizuj i sformatuj zero ujemne.
  • Poprawnie przeanalizuj Infinity i NaN wykonując sprawdzanie bez uwzględniania wielkości liter i zezwalając na opcjonalne poprzednie + , jeśli ma to zastosowanie.

Nowe System.Math interfejsy API obejmują:

  • BitIncrement(Double) i BitDecrement(Double)
    Odpowiada operacjom nextUp IEEE i nextDown . Zwracają najmniejszą liczbę zmiennoprzecinkową, która porównuje liczbę większą lub mniejszą od danych wejściowych (odpowiednio). Na przykład Math.BitIncrement(0.0) zwraca double.Epsilonwartość .

  • MaxMagnitude(Double, Double) i MinMagnitude(Double, Double)
    Odpowiada operacjom maxNumMag i minNumMag IEEE, zwracają wartość większą lub mniejszą niż wielkość dwóch danych wejściowych (odpowiednio). Na przykład Math.MaxMagnitude(2.0, -3.0) zwraca -3.0wartość .

  • ILogB(Double)
    logB Odpowiada operacji IEEE, która zwraca wartość całkowitą, zwraca całkowity dziennik base-2 parametru wejściowego. Ta metoda jest skutecznie taka sama jak floor(log2(x)), ale wykonywana z minimalnym błędem zaokrąglania.

  • ScaleB(Double, Int32)
    scaleB Odpowiada operacji IEEE, która przyjmuje wartość całkowitą, zwraca skutecznie x * pow(2, n)wartość , ale jest wykonywana z minimalnym błędem zaokrąglania.

  • Log2(Double)
    log2 Odpowiada operacji IEEE, zwraca logarytm base-2. Minimalizuje błąd zaokrąglania.

  • FusedMultiplyAdd(Double, Double, Double)
    fma Odpowiada operacji IEEE, wykonuje sumę pomnożną połączoną. Oznacza to, że jest (x * y) + z to pojedyncza operacja, co minimalizuje błąd zaokrąglania. Przykładem jest FusedMultiplyAdd(1e308, 2.0, -1e308)funkcja , która zwraca wartość 1e308. Funkcja regularna (1e308 * 2.0) - 1e308 zwraca wartość double.PositiveInfinity.

  • CopySign(Double, Double)
    copySign Odpowiada operacji IEEE, zwraca wartość x, ale ze znakiem y.

Funkcje wewnętrzne zależne od platformy .NET

Dodano interfejsy API, które umożliwiają dostęp do określonych instrukcji dotyczących procesora CPU zorientowanych na dane, takich jak zestawy instrukcji SIMD lub manipulowania bitami. Te instrukcje mogą pomóc w osiągnięciu znaczących ulepszeń wydajności w niektórych scenariuszach, takich jak wydajne przetwarzanie danych równolegle.

W razie potrzeby biblioteki platformy .NET zaczęły korzystać z tych instrukcji w celu zwiększenia wydajności.

Aby uzyskać więcej informacji, zobacz Funkcje wewnętrzne zależne od platformy .NET.

Ulepszone interfejsy API wersji platformy .NET Core

Począwszy od platformy .NET Core 3.0, interfejsy API wersji dostarczone z platformą .NET Core zwracają teraz oczekiwane informacje. Na przykład:

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

Ostrzeżenie

Zmiana powodująca niezgodność. Jest to technicznie zmiana powodująca niezgodność, ponieważ schemat przechowywania wersji uległ zmianie.

Szybka obsługa wbudowanego kodu JSON

Użytkownicy platformy .NET w dużej mierze polegali na pliku Newtonsoft.Json i innych popularnych bibliotekach JSON, które nadal są dobrymi wyborami. Newtonsoft.Json używa ciągów .NET jako podstawowego typu danych, który jest utF-16 pod maską.

Nowa wbudowana obsługa kodu JSON to wysoka wydajność, niska alokacja i współpracuje z tekstem JSON zakodowanym w formacie UTF-8. Aby uzyskać więcej informacji na temat System.Text.Json przestrzeni nazw i typów, zobacz następujące artykuły:

Obsługa protokołu HTTP/2

Typ System.Net.Http.HttpClient obsługuje protokół HTTP/2. Jeśli protokół HTTP/2 jest włączony, wersja protokołu HTTP jest negocjowana za pośrednictwem protokołu TLS/ALPN, a protokół HTTP/2 jest używany, jeśli serwer zdecyduje się go użyć.

Domyślny protokół pozostaje http/1.1, ale protokół HTTP/2 można włączyć na dwa różne sposoby. Najpierw możesz ustawić komunikat żądania HTTP, aby używał protokołu HTTP/2:

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

Po drugie możesz zmienić HttpClient ustawienie na użycie protokołu HTTP/2 domyślnie:

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

Wiele razy podczas tworzenia aplikacji chcesz użyć niezaszyfrowanego połączenia. Jeśli wiesz, że docelowy punkt końcowy będzie używać protokołu HTTP/2, możesz włączyć niezaszyfrowane połączenia dla protokołu HTTP/2. Możesz ją włączyć, ustawiając zmienną DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT środowiskową na 1 lub włączając ją w kontekście aplikacji:

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

Następne kroki