代码改变世界

[翻译] .NET Core 2.1 Preview 1 发布

2018-03-01 17:17  Rwing  阅读(1815)  评论(17编辑  收藏  举报

[翻译] .NET Core 2.1 Preview 1 发布

原文: Announcing .NET Core 2.1 Preview 1

今天,我们宣布发布 .NET Core 2.1 Preview 1。这是 .NET Core 2.1 的第一个公开发布。我们有很大的改进希望分享出来,并且渴望得到您的反馈意见,无论是在评论中还是在github中dotnet/core #1297

ASP.NET Core 2.1 Preview 1Entity Framework 2.1 Preview 1 也会在今天发布。

您可以在 Windows,MacOS 和 Linux 上下载并开始使用 .NET Core 2.1 Preview 1:

您可以使用 Visual Studio 2017 15.6 Preview 6 及更高版本或 Visual Studio Code 来开发 .NET Core 2.1 应用程序。我们预计 Visual Studio for Mac 将在 15.7 版本支持。

ASP.NET Core 2.1 预览版不会自动部署到 Azure 应用服务。相应的,您可以通过一点点配置来实现部署到 Azure

Visual Studio Team Service 将在 .NET Core 2.1 RTM 发布时支持。

您可以在 .NET Core 2.1 Preview 1 发行说明中看到该发行版的完整详细信息。发行说明中包含已知问题和解决方法。

非常感谢帮助发布的每个人。如果没有你,我们不可能走到现在,当我们一起工作到 .NET Core 2.1 RTM 时,我们会继续需要你的帮助。

现在让我们来看看 .NET Core 2.1 Preview 1 发布中的许多改进。与 .NET Core 2.0 一样,它的发行版本很大,你会找到多项改进措施,以便让你升级。

主题

.NET Core 2.1 的发布旨在改进以下主题:

  • 更快的构建性能
  • 缩小 ASP.NET Core 和 EF Core 之间差距 (原文: Close gaps in ASP.NET Core and EF Core)
  • 改进与 .NET Framework 的兼容性
  • GDPR 和安全
  • 微服务和Azure
  • 更强大的工程系统

这些主题的一些改进尚未在 Preview 1 中进行。这些主题会指引我们接下来的工作。

全局工具

.NET Core 现在有一个新部署和扩展机制。这种新体验与 NPM 全局工具非常相似,并且受到 NPM 全局工具的启发。

使用以下命令,您可以使用我们发布的名为 dotnetsay 的示例工具自行尝试 .NET Core 全局工具(在您安装 .NET Core 2.1 Preview 1 之后):

dotnet install tool -g dotnetsay
dotnetsay

一旦你安装了dotnetsay,你可以直接使用它,只需在你的命令提示符或终端中输入dotnetsay即可。您可以关闭终端会话、在终端中切换驱动器、或者重新启动机器,命令仍然在那里。 dotnetsay 现在在你的 path 里。检查 %USERPROFILE%\.dotnet\tools~\.dotnet\tools 来查看计算机上的工具安装位置。

您可以通过查看 donetsay 工具示例 来创建自己的全局工具。
You can create your own global tools by looking at the donetsay tools sample.

.NET Core 工具是 .NET Core 控制台应用程序,它们是作为 NuGet 包打包和获取的。默认情况下,这些工具是框架依赖的应用程序,并包含其所有的 NuGet 依赖项。这意味着默认情况下,给定的全局工具将在任何操作系统或芯片架构上运行。假如您需要在新版本的 Linux 上使用现有工具,只要 .NET Core 在那里工作,您应该能够运行该工具。

目前,.NET Core Tools 仅支持全局安装,并且需要安装-g参数。我们也在进行各种形式的本地安装,但这些还没有准备好在 Preview 1 中。

我们期望有一个全新的工具生态系统来为完善 .NET 自身。其中一些工具将专门针对 .NET Core 开发,其中许多工具将具有通用性。这些工具被部署到 NuGet。默认情况下,使用 dotnet tool install 在 NuGet.org 上查找工具。

如果你对 dotnetay 很好奇,它是仿照 docker/whalesay 的, 进一步是仿照 cowsay 的。 dotnetsay 只是一个 dotnet-bot,他是我们最忙碌的开发人员之一!

构建性能优化

.NET Core 2.1 中的构建时性能得到了很大的提升,特别是对于增量构建。这些改进同时适用于命令行上的dotnet build 和 Visual Studio 中的构建。 我们对 CLI 工具和 MSBuild 进行了改进,以使这些工具提供更快的体验。

下面的图表提供了您可以从新版本中获得的改进的具体数字。您可以看到 .NET Core 2.0,.NET Core 2.1 Preview 1 以及我们预期 .NET Core RTM 中会达到的数值。

您可以尝试在 mikeharder/dotnet-cli-perf 中自行构建相同的代码,你会得到类似的结果。请注意,这些改进是针对增量构建的,因此您只能在第二次构建之后看到好处。

次要版本前滚

您现在可以在相同主要版本范围内的较新运行时版本上运行 .NET Core 应用程序。 例如,您将能够在. NET Core 2.1 上运行 .NET Core 2.0 应用程序,或者在 .NET Core 2.5 上运行 .NET Core 2.1 应用程序(如果我们提供这种版本的话)。前滚行为仅适用于次要版本。例如,.NET Core 2.x 应用程序永远不会自动前滚到 .NET Core 3.0 或更高版本。

如果预期的 .NET Core 版本可用,则使用它。 如果预期的 .NET Core 版本在给定的环境中不可用,则前滚行为仅与此相关。

您可以使用如下参数禁用次要版本前滚

  • 环境变量: DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=0
  • runtimeconfig.json: rollForwardOnNoCandidateFx=0
  • CLI: –roll-forward-on-no-candidate-fx=0

Sockets 性能和 HTTP 托管处理程序

我们对 .NET Core 2.1 中的 sockets 进行了重大改进。sockets 是传出和传入网络通信的基础。在 .NET Core 2.0 中,ASP.NET Kestrel Web 服务器和 HttpClient 使用 native sockets,而不是 .NET Socket 类。我们正在改变这种状况,取而代之的是在 .NET sockets 上建立更高层次的网络 API。

我们在 Preview 1 中对 sockets 做了三项重要的性能改进:

  • 支持 Socket/NetworkStream 中的 Span/Memory
  • 改进了 Windows 和 Linux 上的性能, 这得益于各种修复(例如重用 PreAllocatedOverlapped、linux 上的缓存操作对象、linux epoll 通知的改进调度等)
  • 改进了 SslStream 的性能, 以及支持 ALPN (HTTP2 所需) 和精简 SslStream 设置。

对于 HttpClient,我们彻底重新构建了一个名为 SocketHttpHandler 的托管 HttpClientHandler。正如你可能猜到的那样,它是基于 .NET sockets 和 Span 的 HttpClient 的 C# 实现。

SocketHttpHandler 最大的胜利就是性能。它比现有的实现快得多。还有其他好处:

  • 消除对 libcurl (linux) 和 WinHTTP (Windows) 的平台依赖性 - 简化了开发、部署和服务

  • 跨平台和平台/依赖项版本的一致行为。(原文:Consistent behavior across platforms and platform/dependency versions)

在 Preview 1 中,您可以选择使用以下方式之一来使用 SocketHTTPHandler:

  • **环境变量: **COMPlus_UseManagedHttpClientHandler=true
  • **AppContext: **System.Net.Http.UseManagedHttpClientHandler=true

在 Preview 2 (或 GitHub master 分支) 中, 您将能够按照您所希望的那样去new一个处理程序: new HttpClient(new SocketsHttpHandler())。我们还考虑将新的处理程序设置为默认的, 并将现有的 native handler (基于 libcurl 和 WinHTTP) 作为可选的。

我们仍在努力将 Kestrel 迁移到 sockets。我们还没有确定计划来分享给大家,但您可以自行使用 Sockets 来测试 ASP.NET Core

您可能想知道在传入和传出场景之间如何共享 sockets 改进的, 因为它们感觉非常不同。其实很简单。如果您是客户端, 则在服务器上进行连接。如果您是服务器, 则侦听并等待连接。一旦建立了连接, 数据就可以两种方式流动, 这从性能的角度来看是至关重要的。因此, 这些 socket 改进应改善这两种情况。

Span, Memory and friends

我们正在引入一组新的类型来更高效的使用数组和其他类型的内存。它们包含在 Preview 1 中。今天,如果您想传递10,000元素数组的前1000个元素,则需要复制这1000个元素并将该副本传递给调用者。这种操作在时间和空间上都很昂贵。新的 Span 类型使您可以提供该数组的虚拟视图,而无需时间或空间开销。这也是一个 struct,这意味着没有分配成本。

Span 和相关类型提供了来自众多不同来源(如数组,堆栈分配和原生代码)的统一内存表示。凭借其分片功能,可以避免在许多情况下进行昂贵的复制和分配,如字符串处理,缓冲区管理等,并且为不安全的代码提供了安全的替代方案。我们预计这些类型将在性能要求较高的场景中首先使用,但随后会取代数组,作为管理 .NET 中大型数据块的主要方式。

就用法而言,您可以从数组中创建一个Span

var arr = new byte[10]; 
Span<byte> bytes = arr; // Implicit cast from T[] to Span<T>

通过使用 span 切片方法的重载, 您可以轻松高效地创建一个范围来表示/指向此数组的子集。从那里, 您可以索引到结果范围内, 以便在原始数组的相关部分中写入和读取数据:

Span<byte> slicedBytes = bytes.Slice(start: 5, length: 2);
slicedBytes[0] = 42;
slicedBytes[1] = 43;
Assert.Equal(42, slicedBytes[0]);
Assert.Equal(43, slicedBytes[1]);
Assert.Equal(arr[5], slicedBytes[0]);
Assert.Equal(arr[6], slicedBytes[1]);
slicedBytes[2] = 44; // Throws IndexOutOfRangeException
bytes[2] = 45; // OK
Assert.Equal(arr[2], bytes[2]);
Assert.Equal(45, arr[2]);

Jared Parsons 他的频道9视频中提供了一个很棒的介绍 C# 7.2: Understanding Span.
Stephen Toub 有更详细的介绍在这个文章里 C# – All About Span: Exploring a New .NET Mainstay.

Windows Compatibility Pack

将现有代码从 .NET Framework 中移植到 .NET Core 时, 可以使用新的 Windows 兼容性包。与 .NET Core 中提供的内容相比, 它提供了额外的 20000 个 API。这包括System.Drawing, EventLog, WMI, 性能计数器和 Windows 服务。

下面的示例演示如何使用 Windows 兼容性包提供的 API 访问 windows 注册表。

private static string GetLoggingPath()
{
    // Verify the code is running on Windows.
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam\AssetManagement"))
        {
            if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
                return configuredPath;
        }
    }

    // This is either not running on Windows or no logging path was configured,
    // so just use the path for non-roaming user-specific data files.
    var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    return Path.Combine(appDataPath, "Fabrikam", "AssetManagement", "Logging");
}

平台支持

我们期望为 .NET Core 2.1 支持以下操作系统

  • Windows Client: 7, 8.1, 10 (1607+)
  • Windows Server: 2008 R2 SP1+
  • macOS: 10.12+
  • RHEL: 7+
  • Fedora: 26+
  • openSUSE: 42.3+
  • Debian: 8+
  • Ubuntu: 14.04, 16.04, 17.10+
  • SLES: 12+
  • Alpine: 3.6+

Docker

对于 Docker, 在 microsoft/dotnet 上我们相对于 2.0 做了一些修改:

  • 添加了 Alpine runtime 和 SDK 镜像 (x64).
  • 添加了 Ubuntu Bionic/18.04, 用于 runtime 和 SDK 镜像 (x64 and ARM32).
  • 从 debian:stretch 切换到 debian:stretch-slim 的 runtime 镜像. (x64 and ARM32).
  • 放弃 debian:jessie (runtime and SDK).

这些变化在某种程度上是基于我们在过去六个月中听到的两个重复的反馈信息:

  • 提供更小的镜像,尤其是 runtime
  • Provide images with less surface area and/or more frequently updated (than Debian), from a vulnerability standpoint.

我们还重写了 .NET Core Docker 示例 的说明和代码。
这些示例提供了更好的说明,并实现了更多场景,如单元测试和使用 docker registries。 我们希望您找到有用的示例,并且我们计划继续扩展它们。 告诉我们您希望我们添加哪些内容以使 .NET Core 和 Docker 更好地协同工作

尾声

感谢您尝试 .NET Core 2.1 Preview 1. 请尝试在现有的应用程序中使用 .NET Core 2.1 Preview 1,并且请试用本文介绍的新功能。 我们已经付出了很多努力使它们更好,但我们需要您的反馈让它们跨过终点线,以便最终发布。

再一次感谢所有为发布做出贡献的人。 我们非常感谢您提供的所有问题和PR,这些都有助于提供此首次预览版。