.NET Core 2.1 的新增功能What's new in .NET Core 2.1

本文内容

.NET Core 2.1 提供以下几个方面的增强功能和新功能:

工具Tooling

.NET Core 2.1 SDK (v 2.1.300),该工具与 .NET Core 2.1 一起提供,包括以下更改和增强功能:

生成性能改进Build performance improvements

.NET Core 2.1 的主要关注点是改进生成时性能,特别是增量生成。这些性能改进适用于使用 dotnet build 的两个命令行生成和 Visual Studio 中的生成。一些个别的改进领域包括:

  • 对于包资产解决方法,只解决由生成使用的资产而不是所有资产。

  • 程序集引用缓存。

  • 使用长时间运行的 SDK 生成服务器,这些是跨各个 dotnet build 调用的过程。每次 dotnet build 运行时不再需要 JIT 编译大量代码块。生成服务器进程可以使用以下命令自动终止:

  1. dotnet buildserver shutdown

新的 CLI 命令New CLI commands

许多使用 DotnetCliToolReference 的仅在每个项目的基础上可用的工具现作为 .NET Core SDK 的一部分提供。这些工具包括:

  • dotnet watch 提供文件系统观察程序,该程序在执行指定的命令集之前会首先等待文件更改。例如,下面的命令将自动重新生成当前项目,并在其中的文件发生更改时生成详细输出:
  1. dotnet watch -- --verbose build

请注意 —verbose 选项前面的 选项。它分隔从传递给子 dotnet 进程的参数直接传递到 dotnet watch 命令的选项。如果没有该选项,—verbose 选项将适用于 dotnet watch 命令,而非 dotnet build 命令。

有关详细信息,请参阅使用 dotnet watch 开发 ASP.NET Core 应用

  • dotnet dev-certs 生成和管理在 ASP.NET Core 应用程序开发期间使用的证书。

  • dotnet user-secrets 管理 ASP.NET Core 应用程序中用户机密库的机密。

  • dotnet sql-cache 在 Microsoft SQL Server 数据库中创建表和索引以用于分布式缓存。

  • dotnet ef 是用于管理 Entity Framework Core 应用程序中数据库、DbContext 对象和迁移的工具。有关详细信息,请参阅 EF Core .NET 命令行工具

全局工具Global Tools

.NET Core 2.1 支持全局工具 ,即,可通过命令行在全局范围内使用的自定义工具。以前版本的 .NET Core 中的扩展性模型只能通过使用 DotnetCliToolReference 在每个项目的基础上提供自定义工具。

若要安装全局工具,请使用 dotnet tool install 命令。例如:

  1. dotnet tool install -g dotnetsay

完成安装后,可以通过指定工具名称从命令行运行该工具。有关详细信息,请参阅 .NET Core 工具概述

使用 dotnet tool 命令管理工具Tool management with the dotnet tool command

在 .NET Core 2.1 SDK 中,所有工具操作都使用 dotnet tool 命令。可用选项如下:

前滚Roll forward

从 .NET Core 2.0 开始,所有 .NET Core 应用程序都将自动前滚到系统上安装的最新次要版本 。

从 .NET Core 2.0 开始,如果在其中构建应用程序的 .NET Core 版本在运行时不存在,应用程序将针对最新安装的次要版本 的 .NET Core 自动运行。换而言之,如果应用程序在 .NET Core 2.0 中生成,而主机系统未安装 .NET Core 2.0 但安装了 .NET Core 2.1,则应用程序将通过 .NET Core 2.1 运行。

重要

此前滚行为不适用于预览版本。默认情况下,它也不适用于主要版本,但可以通过以下设置进行更改。

可以通过在没有候选共享框架的情况下更改前滚设置来修改此行为。可用设置如下:

  • 0 - 禁用次要版本前滚行为。使用此设置,为 .NET Core 2.0.0 构建的应用程序将前滚到 .NET Core 2.0.1,但不会前滚到 .NET Core 2.2.0 或 .NET Core 3.0.0。
  • 1 - 启用次要版本前滚行为。这是设置的默认值。使用此设置,为 .NET Core 2.0.0 构建的应用程序将前滚到 .NET Core 2.0.1 或 .NET Core 2.2.0,具体取决于安装的版本,但它不会前滚到 .NET Core3.0.0。
  • 2 - 启用次要和主要版本前滚行为。即使考虑不同的主要版本,如果这样设置,为 .NET Core 2.0.0 构建的应用程序将前滚到 .NET Core 3.0.0。可以通过以下三种方式之一修改此设置:

  • DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX 环境变量设置为所需的值。

  • 使用所需的值将下列行添加到 .runtimeconfig.json 文件:

  1. "rollForwardOnNoCandidateFx" : 0
  • 使用 .NET Core CLI 工具时,请使用所需的值将下列选项添加到 .NET Core 命令,例如 run
  1. dotnet run --rollForwardOnNoCandidateFx=0

修补程序版本前滚与此设置无关,并且在应用任何潜在的次要或主要版本前滚之后完成。

部署Deployment

自包含应用程序服务Self-contained application servicing

dotnet publish 现发布服务运行时版本的自包含应用程序。当你使用 .NET Core 2.1 SDK (v 2.1.300) 发布自包含应用程序时,你的应用程序将包括此 SDK 已知的最新服务运行时版本。当升级到最新的 SDK,将发布最新的 .NET Core 运行时版本。这适用于 .NET Core 1.0 运行时以及更高版本。

自包含发布依赖于 NuGet.org 上的运行时版本。计算机上不需要有服务运行时。

使用 .NET Core 2.0 SDK,自包含应用程序将通过 .NET Core 2.0.0 运行时发布,除非通过 RuntimeFrameworkVersion 属性指定不同版本。借助此新行为,你将不再需要设置此属性便可为自包含的应用程序选择更高版本的运行时。最简单的方法是始终通过 .NET Core 2.1 SDK (v 2.1.300) 发布。

有关详细信息,请参阅独立部署运行时前滚

Windows 兼容包Windows Compatibility Pack

当你将现有代码从 .NET Framework 转移到 .NET Core 时,可以使用 Windows 兼容包除了 .NET Core 中提供的 API,它使你还能够访问额外的 20,000 多个 API。这些 API 包括 System.Drawing 命名空间中的类型、EventLog 类、WMI、性能计数器、Windows 服务以及 Windows 注册表类型和成员。

JIT 编译器改进JIT compiler improvements

.NET Core 包含新的 JIT 编译器技术,称为“分层编译” (也称为“自适应优化” ),可以显著提高性能。分层编译是一个可选设置。

由 JIT 编译器执行的重要任务之一是优化代码执行。然而,对于很少使用的代码路径,相比运行未优化代码所花费的运行时,编译器可能需要更多的时间来优化代码。分层编译介绍了 JIT 编译中的两个阶段:

  • 第一层 ,将尽可能快地生成代码。

  • 第二层 ,将为那些频繁执行的方法生成优化代码。为了增强性能,第二层编译并行执行。

可以通过这两种方法之一选择加入分层编译。

  • 若要在所有使用 .NET Core 2.1 SDK 的项目中使用分层编译,请设置以下环境变量:
  1. COMPlus_TieredCompilation="1"
  • 若要在每个项目的基础上使用分层编译,将 <TieredCompilation> 属性添加到 MSBuild 项目文件的 <PropertyGroup> 部分,如以下示例所示:
  1. <PropertyGroup>
  2. <!-- other property definitions -->
  3. <TieredCompilation>true</TieredCompilation>
  4. </PropertyGroup>

API 更改API changes

Span<T> 和 Memory<T>Span<T> and Memory<T>

.NET Core 2.1 包括一些新类型,使得在使用数组和其他类型内存方面要高效得多。新类型包括:

  • System.SpanSystem.ReadOnlySpan

  • System.MemorySystem.ReadOnlyMemory如果没有这些类型,那么在作为数组的一部分或内存缓冲区的一部分传递此类项时,必须在将数据的某些部分传递给方法之前复制该数据部分。这些类型提供了该数据的虚拟视图,无需额外的内存分配和复制操作。

下面的示例使用 Span<T>Memory<T> 实例来提供一个数组 10 个元素的虚拟视图。

  1. using System;
  2. class Program
  3. {
  4. static void Main()
  5. {
  6. int[] numbers = new int[100];
  7. for (int i = 0; i < 100; i++)
  8. {
  9. numbers[i] = i * 2;
  10. }
  11. var part = new Span<int>(numbers, start: 10, length: 10);
  12. foreach (var value in part)
  13. Console.Write($"{value} ");
  14. }
  15. }
  16. // The example displays the following output:
  17. // 20 22 24 26 28 30 32 34 36 38
  1. Module Program
  2. Sub Main()
  3. Dim numbers As Integer() = New Integer(99) {}
  4. For i As Integer = 0 To 99
  5. numbers(i) = i * 2
  6. Next
  7. Dim part = New Memory(Of Integer)(numbers, start:=10, length:=10)
  8. For Each value In part.Span
  9. Console.Write($"{value} ")
  10. Next
  11. End Sub
  12. End Module
  13. ' The example displays the following output:
  14. ' 20 22 24 26 28 30 32 34 36 38

Brotli 压缩Brotli compression

.NET Core 2.1 添加了对 Brotli 压缩和解压缩的支持。Brotli 是在 RFC 7932 中定义的通用无损压缩算法,并且大多数 Web 浏览器和主 Web 服务器都提供支持。可以使用基于流的 System.IO.Compression.BrotliStream 类或基于范围的高性能 System.IO.Compression.BrotliEncoderSystem.IO.Compression.BrotliDecoder 类。下面的示例用 BrotliStream 类演示压缩:

  1. public static Stream DecompressWithBrotli(Stream toDecompress)
  2. {
  3. MemoryStream decompressedStream = new MemoryStream();
  4. using (BrotliStream decompressionStream = new BrotliStream(toDecompress, CompressionMode.Decompress))
  5. {
  6. decompressionStream.CopyTo(decompressedStream);
  7. }
  8. decompressedStream.Position = 0;
  9. return decompressedStream;
  10. }
  1. Public Function DecompressWithBrotli(toDecompress As Stream) As Stream
  2. Dim decompressedStream As New MemoryStream()
  3. Using decompressionStream As New BrotliStream(toDecompress, CompressionMode.Decompress)
  4. decompressionStream.CopyTo(decompressedStream)
  5. End Using
  6. decompressedStream.Position = 0
  7. Return decompressedStream
  8. End Function

BrotliStream 行为等同于 DeflateStreamGZipStream,这样就可以轻松地将调用这些 API 的代码转换为 BrotliStream

新加密 API 和加密改进New cryptography APIs and cryptography improvements

.NET Core 2.1 包括加密 API 的许多增强功能:

套接字改进Sockets improvements

.NET Core 包括一个新类型 System.Net.Http.SocketsHttpHandler 和重写的 System.Net.Http.HttpMessageHandler,两者构成了更高级别网络 API 的基础。例如,System.Net.Http.SocketsHttpHandlerHttpClient 实现的基础。在以前版本的 .NET Core 中,更高级别的 API 基于本机网络实现。

.NET Core 2.1 中引入的套接字实现具有很多优点:

  • 对照以前的实现,可以看到显著的性能改进。

  • 消除平台依赖项,从而简化部署和维护。

  • 在所有 .NET Core 平台之间保持行为一致。

SocketsHttpHandler 是 .NET Core 2.1 中的默认实现。但是,你可以通过调用 AppContext.SetSwitch 方法配置应用程序以使用较旧的 HttpClientHandler 类:

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

还可以使用环境变量选择退出使用基于 SocketsHttpHandler 的套接字实现。为此,需要将 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 设置为 false 或 0。

在 Windows 上,还可以选择使用 System.Net.Http.WinHttpHandler后者依赖于本机实现),或者通过将类实例传递到 HttpClient 构造函数来使用 SocketsHttpHandler 类。

在 Linux 和 macOS 上,可以在每个进程的基础上仅配置 HttpClient在 Linux 上,如果想要使用旧的 HttpClient 实现,则需要部署 libcurl(它随 .NET Core 2.0 一起安装。)

请参阅See also