Condividi tramite


Novità di .NET Core 2.1

.NET Core 2.1 include miglioramenti e nuove funzionalità nelle aree seguenti:

Strumenti

.NET Core 2.1 SDK (v 2.1.300), ovvero il set di strumenti incluso in .NET Core 2.1, include le modifiche e i miglioramenti seguenti:

Miglioramenti delle prestazioni di compilazione

Un obiettivo fondamentale di .NET Core 2.1 è il miglioramento delle prestazioni in fase di compilazione, in particolare per le compilazioni incrementali. Questi miglioramenti delle prestazioni si applicano sia alle compilazioni dalla riga di comando con dotnet build che alle compilazioni in Visual Studio. Alcune aree specifiche di miglioramento includono:

  • Per la risoluzione degli asset dei pacchetti, risoluzione solo degli asset usati da una compilazione anziché di tutti gli asset.

  • Memorizzazione nella cache dei riferimenti agli assembly.

  • Uso dei server di compilazione SDK a esecuzione prolungata, ovvero processi che si estendono attraverso singole chiamate a dotnet build. Eliminano la necessità di compilare tramite JIT blocchi di codice di grandi dimensioni ogni volta che viene eseguito dotnet build. I processi del server di compilazione possono essere terminati automaticamente con il comando seguente:

    dotnet buildserver shutdown
    

Nuovi comandi dell'interfaccia della riga di comando

Numerosi strumenti precedentemente disponibili solo a livello di singolo progetto usando DotnetCliToolReference sono ora disponibili come parte di .NET Core SDK. Questi strumenti includono:

  • dotnet watch fornisce un watcher del file system che rimane in attesa delle modifiche a un file prima di eseguire un determinato set di comandi. Ad esempio, il comando seguente ricompila automaticamente il progetto corrente e genera un output dettagliato ogni volta che viene modificato un file in esso contenuto:

    dotnet watch -- --verbose build
    

    Si noti l'opzione -- che precede l'opzione --verbose. Delimita le opzioni passate direttamente al comando dotnet watch dagli argomenti passati al processo figlio dotnet. Senza di essa, l'opzione --verbose si applica al comando dotnet watch e non al comando dotnet build.

    Per altre informazioni, vedere Sviluppare app ASP.NET Core con dotnet watch.

  • dotnet dev-certs genera e gestisce i certificati usati durante lo sviluppo nelle applicazioni ASP.NET Core.

  • dotnet user-secrets gestisce i segreti in un archivio di segreti dell'utente nelle applicazioni ASP.NET Core.

  • dotnet sql-cache crea una tabella e gli indici in un database di Microsoft SQL Server da usare per la memorizzazione nella cache distribuita.

  • dotnet ef è uno strumento per la gestione di database, oggetti DbContext e migrazioni in applicazioni Entity Framework Core. Per altre informazioni, vedere Strumenti da riga di comando di EF Core .NET.

Strumenti globali

.NET Core 2.1 supporta gli strumenti globali, vale a dire strumenti personalizzati disponibili globalmente dalla riga di comando. Il modello di estendibilità nelle versioni precedenti di .NET Core rendeva disponibili gli strumenti personalizzati a livello di singolo progetto solo usando DotnetCliToolReference.

Per installare uno strumento globale, usare il comando dotnet tool install. Ad esempio:

dotnet tool install -g dotnetsay

Dopo l'installazione, lo strumento può essere eseguito dalla riga di comando specificando il nome dello strumento. Per altre informazioni, vedere Panoramica degli strumenti globali .NET Core.

Strumento di gestione con il comando dotnet tool

In .NET Core 2.1 SDK tutte le operazioni con gli strumenti usano il comando dotnet tool. Sono disponibili le seguenti opzioni:

Avanzamento

Di tutte le applicazioni .NET Core a partire da .NET Core 2.0 viene eseguito automaticamente il roll forward alla versione secondaria più recente installata in un sistema.

A partire da .NET Core 2.0, se la versione di .NET Core con cui è stata compilata un'applicazione non è presente in fase di esecuzione, l'applicazione verrà eseguita automaticamente con la versione secondaria installata più recente di .NET Core. In altre parole, se un'applicazione è compilata con .NET Core 2.0 e .NET Core 2.0 non è presente nel sistema host ma .NET Core 2.1 lo è, l'applicazione verrà eseguita con .NET Core 2.1.

Importante

Questo comportamento di roll forward non si applica alle versioni di anteprima, Per impostazione predefinita, non si applica nemmeno alle versioni principali, ma il comportamento si può modificare con le impostazioni seguenti.

Per modificare questo comportamento, cambiare l'impostazione per il roll forward scegliendo di non eseguirlo su framework condiviso candidato. Le impostazioni disponibili sono:

  • 0 - Disabilitare il comportamento del roll forward per la versione secondaria. Con questa impostazione, un'applicazione creata per .NET Core 2.0.0 esegue il roll forward a .NET Core 2.0.1, ma non a .NET Core 2.2.0 o .NET Core 3.0.0.
  • 1 - Abilitare il comportamento del roll forward per la versione secondaria. Questo è il valore predefinito per l'impostazione. Con questa impostazione, un'applicazione creata per .NET Core 2.0.0 esegue il roll forward a .NET Core 2.0.1 o a .NET Core 2.2.0, a seconda di quale dei due è installato, ma non a .NET Core 3.0.0.
  • 2 - Abilitare il comportamento del roll forward per le versioni principale e secondaria. Se impostata, vengono considerate anche diverse versioni principali, in modo che un'applicazione compilata per .NET Core 2.0.0 esegua il roll forward a .NET Core 3.0.0.

È possibile modificare questa impostazione in tre modi:

  • Impostare la variabile di ambiente DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX su un valore.

  • Aggiungere la riga seguente con il valore desiderato al file .runtimeconfig.json:

    "rollForwardOnNoCandidateFx" : 0
    
  • Quando si usa l'interfaccia della riga di comando di .NET, aggiungere l'opzione seguente con il valore desiderato a un comando di .NET, ad esempio run:

    dotnet run --rollForwardOnNoCandidateFx=0
    

Il roll forward della versione della patch è indipendente da questa impostazione e viene eseguito dopo gli eventuali roll forward della versione principale o secondaria.

Distribuzione

Manutenzione di un'applicazione autonoma

dotnet publish pubblica ora applicazioni autonome con una versione runtime servita. Quando si pubblica un'applicazione autonoma con .NET Core 2.1 SDK (v 2.1.300), l'applicazione include l'ultima versione runtime servita conosciuta da tale SDK. Quando si esegue l'aggiornamento all'SDK più recente, si pubblicherà con l'ultima versione runtime di .NET Core. Questo vale per i runtime di .NET Core 1.0 e versioni successive.

La pubblicazione autonoma si basa sulle versioni runtime in NuGet.org. Non è necessario disporre del runtime servito nel computer.

Tramite .NET Core 2.0 SDK, le applicazioni autonome sono pubblicate con il runtime .NET Core 2.0.0, a meno che non venga specificata un'altra versione tramite la proprietà RuntimeFrameworkVersion. Con questo nuovo comportamento, non sarà più necessario impostare questa proprietà per selezionare una versione runtime successiva per un'applicazione autonoma. L'approccio più semplice in futuro consiste nel pubblicare sempre con .NET Core 2.1 SDK (v 2.1.300).

Per altre informazioni, vedere Roll forward del runtime di distribuzione autonoma.

Pacchetto di Compatibilità Windows

Quando si porta il codice esistente da .NET Framework a .NET Core, è possibile usare Windows Compatibility Pack, che garantisce l'accesso a 20.000 API in più rispetto a quelle disponibili in .NET Core. Queste API includono tipi nello spazio dei nomi System.Drawing, la classe EventLog, WMI, contatori delle prestazioni, servizi di Windows e tipi e membri del Registro di sistema di Windows.

Miglioramenti del compilatore JIT

.NET Core include una nuova tecnologia del compilatore JIT denominata compilazione a livelli (nota anche come ottimizzazione adattiva) che può migliorare significativamente le prestazioni. La compilazione a livelli è un'impostazione che prevede il consenso esplicito.

Una delle attività importanti eseguite dal compilatore JIT è l'ottimizzazione dell'esecuzione del codice. Per i percorsi del codice poco usati, tuttavia, il compilatore può richiedere più tempo per l'ottimizzazione del codice rispetto a quanto impiegato dal runtime per l'esecuzione del codice non ottimizzato. La compilazione a livelli introduce due fasi nella compilazione JIT:

  • Un primo livello, che genera il codice il più rapidamente possibile.

  • Un secondo livello, che genera codice ottimizzato per i metodi che vengono eseguiti frequentemente. Il secondo livello di compilazione viene eseguito in parallelo per prestazioni migliorate.

È possibile acconsentire esplicitamente alla compilazione a livelli in uno dei due modi seguenti.

  • Per usare la compilazione a livelli in tutti i progetti che usano .NET Core 2.1 SDK, impostare la variabile di ambiente seguente:

    COMPlus_TieredCompilation="1"
    
  • Per usare la compilazione a livelli in base al progetto, aggiungere la proprietà <TieredCompilation> alla sezione <PropertyGroup> del file di progetto MSBuild, come illustrato nell'esempio seguente:

    <PropertyGroup>
        <!-- other property definitions -->
    
        <TieredCompilation>true</TieredCompilation>
    </PropertyGroup>
    

Modifiche API

Span<T> e Memory<T>

.NET Core 2.1 include alcuni nuovi tipi che rendono molto più efficiente l'uso di matrici e altri tipi di memoria. I nuovi tipi includono:

Senza questi tipi, quando si passano elementi quali una parte di una matrice o una sezione di un buffer di memoria, è necessario creare una copia di una parte dei dati prima di passarli a un metodo. Questi tipi forniscono una visualizzazione virtuale dei dati che elimina la necessità di un'allocazione di memoria e di operazioni di copia aggiuntive.

L'esempio seguente usa un'istanza Span<T> e un'istanza Memory<T> per fornire una visualizzazione virtuale di 10 elementi di una matrice.

using System;

class Program
{
    static void Main()
    {
        int[] numbers = new int[100];
        for (int i = 0; i < 100; i++)
        {
            numbers[i] = i * 2;
        }

        var part = new Span<int>(numbers, start: 10, length: 10);
        foreach (var value in part)
            Console.Write($"{value}  ");
    }
}
// The example displays the following output:
//     20  22  24  26  28  30  32  34  36  38
Module Program
    Sub Main()
        Dim numbers As Integer() = New Integer(99) {}

        For i As Integer = 0 To 99
            numbers(i) = i * 2
        Next

        Dim part = New Memory(Of Integer)(numbers, start:=10, length:=10)

        For Each value In part.Span
            Console.Write($"{value}  ")
        Next
    End Sub
End Module
' The example displays the following output:
'     20  22  24  26  28  30  32  34  36  38

Compressione Brotli

.NET Core 2.1 aggiunge il supporto per la compressione e la decompressione Brotli. Brotli è un algoritmo di compressione generico senza perdita di dati definito in RFC 7932 e supportato dalla maggior parte dei Web browser e dai principali server Web. È possibile usare la classe System.IO.Compression.BrotliStream basata sul flusso o le classi System.IO.Compression.BrotliEncoder e System.IO.Compression.BrotliDecoder basate sull'intervallo a prestazioni elevate. L'esempio seguente illustra la compressione con la classe BrotliStream:

public static Stream DecompressWithBrotli(Stream toDecompress)
{
    MemoryStream decompressedStream = new MemoryStream();
    using (BrotliStream decompressionStream = new BrotliStream(toDecompress, CompressionMode.Decompress))
    {
        decompressionStream.CopyTo(decompressedStream);
    }
    decompressedStream.Position = 0;
    return decompressedStream;
}
Public Function DecompressWithBrotli(toDecompress As Stream) As Stream
    Dim decompressedStream As New MemoryStream()
    Using decompressionStream As New BrotliStream(toDecompress, CompressionMode.Decompress)
        decompressionStream.CopyTo(decompressedStream)
    End Using
    decompressedStream.Position = 0
    Return decompressedStream
End Function

Il comportamento di BrotliStream è lo stesso di DeflateStream e GZipStream, che rende più facile convertire il codice che chiama queste API in BrotliStream.

Nuove API di crittografia e miglioramenti della crittografia

.NET Core 2.1 include numerosi miglioramenti alle API di crittografia:

Miglioramenti del socket

.NET Core include un nuovo tipo, System.Net.Http.SocketsHttpHandler, e un tipo System.Net.Http.HttpMessageHandler riscritto, che costituiscono la base delle API di rete di livello superiore. System.Net.Http.SocketsHttpHandler, ad esempio, è la base dell'implementazione di HttpClient. Nelle versioni precedenti di .NET Core le API di livello superiore si basavano su implementazioni di rete native.

L'implementazione dei socket introdotta in .NET Core 2.1 comporta numerosi vantaggi:

  • Miglioramento significativo delle prestazioni rispetto all'implementazione precedente.

  • Eliminazione delle dipendenze della piattaforma, con una conseguente semplificazione della distribuzione e della manutenzione.

  • Comportamento coerente in tutte le piattaforme .NET Core.

SocketsHttpHandler è l'implementazione predefinita in .NET Core 2.1. Tuttavia, è possibile configurare l'applicazione per usare la classe HttpClientHandler precedente chiamando il metodo AppContext.SetSwitch:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", False)

È anche possibile usare una variabile di ambiente per rifiutare esplicitamente l'uso di implementazioni dei socket basate su SocketsHttpHandler. A tale scopo, impostare DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER su false o su 0.

In Windows è anche possibile scegliere di usare System.Net.Http.WinHttpHandler, che si basa su un'implementazione nativa, o la classe SocketsHttpHandler passando un'istanza della classe al costruttore HttpClient.

In Linux e macOS è possibile configurare HttpClient solo in base al processo. In Linux è necessario distribuire libcurl se si vuole usare l'implementazione precedente di HttpClient (installato con .NET Core 2.0).

Modifiche di rilievo

Per informazioni sulle modifiche che causano un'interruzione, vedere Modifiche che causano un'interruzione per la migrazione dalla versione 2.0 alla versione 2.1.

Vedi anche