今日是一年一度光棍节,首先祝各位码农朋友们节日快乐,在关注技术的同时也要同时关注另一半,争取早日脱单,今天不过节,只专心于技术!
今天微软开发团队宣布发布.NET 5.0正式版。主要更新包括C#9和F#5在内的一系列新功能和改进。同期发布了ASP.NET Core,EF Core,C#9和F#5。可以在官方下载页面下载跨平台包括Windows,macOS和Linux和跨处理架构包括x86,x64,Arm32,Arm64。
Windows Visual Studio用户,需要Visual Studio 16.8或更高版本才能支持.NET 5.0,在macOS用户,需要 Visual Studio for Mac的最新版本。VS Code的C#插件已经完全支持.NET 5.0和C#9。
一、.NET 5.0亮点
带来了大量的功能改进,其中最亮眼的是:
- .NET 5.0已通过在dot.net和Bing()上托管,进行了数月来的测试。性能和稳定性上有很大的提高。
- C#9和F#5 带了新的语言改进,例如C#9的Top-level编程和记录,F#5提供了交互式编程,并提高了.NET上的功能性编程的性能。
- .NET库方面增强了Json序列化,正则表达式和HTTP(HTTP 1.1,HTTP/2)的性能。
- 由于改进了GC,分层编译和其他方面,P95延迟有所减少。
- 通过ClickOnce客户端应用程序发布,单文件应用程序,减小的容器映像大小以及添加的Server Core容器映像,应用程序部署选项更好。
- Windows Arm64和WebAssembly扩展了平台范围。
1. 跨平台和Microsoft支持
.NET 5.0有一个和.NET 3.1几乎相同的平台支持矩阵核心,适用于Windows,MacOS和Linux操作系统。如果操作系统支持使用.NET Core 3.1,则大多数情况下应该可以升级使用.NET 5.0。.NET 5.0最重要的新增功能是Windows Arm64。
.NET 5.0发布三个月后,会发布一个LTS版本.NET 6.0,.NET5.0技术支持会持续到2022年2月中。.NET6.0技术支持期为三年。
.NET 5.0是微软第一个统一平台愿景的实现版本,可以使用一组API,语言和工具来针对广泛的应用程序类型,包括移动,云,桌面和IoT。
实现这一愿景的第一步是整合.NET仓库,其中包括很大一部分的Mono。为.NET运行库和库提供一个存储库是在各处交付相同产品的前提。它还有助于进行广泛的更改,这些更改会影响运行时和库,这些存储库以前具有回购边界。有些人担心大型回购交易将更难管理。事实并非如此。
在.NET 5.0版本中,Blazor是利用回购合并和.NET统一的最佳示例。Blazor WebAssembly的运行时和库现在是从合并的dotnet /运行时库中构建的。服务器上的Blazor WebAssembly和Blazor使用完全相同的代码。
2. 语言功能
作为.NET 5.0版本的一部分,C#9和F#5被包含在.NET 5.0 SDK中。Visual SDK也包含在5.0 SDK中。它不包括语言更改,但做了改进以支持.NET Core上的Visual Basic应用程序框架。
3. Top-level编程
Top-level编程是C#9中新推出的功能,下面一个led灯控制的演示程序,是官方Top-level编程的示例:
- using System;
- using System.Device.Gpio;
- using System.Threading;
- var pin = 18;
- var lightTime = 1000;
- var dimTime = 200;
- Console.WriteLine($"Let's blink an LED!");
- using GpioController controller = new ();
- controller.OpenPin(pin, PinMode.Output);
- Console.WriteLine($"GPIO pin enabled for use: {pin}");
- // turn LED on and off
- while (true)
- {
- Console.WriteLine($"Light for {lightTime}ms");
- controller.Write(pin, PinValue.High);
- Thread.Sleep(lightTime);
- Console.WriteLine($"Dim for {dimTime}ms");
- controller.Write(pin, PinValue.Low);
- Thread.Sleep(dimTime);
- }
从示例中可以看到target-typed的使用以及new对controller变量的分配。GpioController类型在定义等式左侧所定义。而类型是在右侧推断的。该新语法是得替代传统的var方法。
通过定义方法并利用同一文件或其他文件中定义的类型,Top-level编程还可能更加复杂。
4. 逻辑和属性模式
C#9包括对新模式的支持。下面的CCS811气体传感器程序是逻辑模式的示例:
- var threshChoice = Console.ReadKey();
- Console.WriteLine();
- if (threshChoice.KeyChar is 'Y' or 'y')
- {
- TestThresholdAndInterrupt(ccs811);
- }
另一个新模式是属性模式。可以在Mycroft Information Access 6.0示例中看到几个属性检查。在下面的代码是从所拍摄的PN532 RFID和NFC读取器示例:
- if (pollingType is not { Length: <=15 })
- {
- return null;
- }
该代码测试pollingType是否为null或包含>15个字节。用来作为返回之前要测试的两个错误条件。测试条件可以写:
- byte[]?nullpollingType is null or { Length: > 15 }
另外两种模式。第一个是逻辑图形中Mcp25xxx CAN总线。
- public static byte GetRxBufferNumber(Address address) => address switch
- {
- >= Address.RxB0D0 and <= Address.RxB0D7 => 0,
- >= Address.RxB1D0 and <= Address.RxB1D7 => 1,
- _ => throw new ArgumentException(nameof(address), $"Invalid address value {address}."),
- };
第二个是一个逻辑模式在压电蜂鸣器控制器。
- if (element is not NoteElement noteElement)
- {
- // In case it's a pause element we have only just wait desired time.
- Thread.Sleep(durationInMilliseconds);
- }
- else
- {
- var frequency = GetFrequency(noteElement.Note, noteElement.Octave);
- _buzzer.PlayTone(frequency, (int)(durationInMilliseconds * 0.7));
- Thread.Sleep((int)(durationInMilliseconds * 0.3));
- }
5. 记录
C#9包括一种称为记录的新型类。与常规类相比,它具有许多优点,其中一半与更简洁的语法有关。在下面的记录是Bh1745 RGB传感器的示例:
- public record ChannelCompensationMultipliers(double Red, double Green, double Blue, double Clear);
可以这样给其赋值:
- ChannelCompensationMultipliers = new (2.2, 1.0, 1.8, 10.0);
6. 可空断言改进
.NET库现在已完全支持可空断言。如果启用可空性,将从平台上获取更多类型信息。
大类通常在从构造函数调用的帮助器方法中实例化对象成员。C#编译器无法遵循对对象分配的调用流程。退出构造函数时,它会认为该成员为null,并使用发出警告CS8618。MemberNotNull属性可解决此问题。该属性应用于助手方法。然后,编译器将看到设置了该值,并意识到该方法是从构造函数中调用的。
下面是一个在BMxx80温度传感器中的示例:
- [MemberNotNull(nameof(_calibrationData))]
- private void ReadCalibrationData()
- {
- switch (this)
- {
- case Bme280 _:
- _calibrationData = new Bme280CalibrationData();
- _controlRegister = (byte)Bmx280Register.CTRL_MEAS;
- break;
- case Bmp280 _:
- _calibrationData = new Bmp280CalibrationData();
- _controlRegister = (byte)Bmx280Register.CTRL_MEAS;
- break;
- case Bme680 _:
- _calibrationData = new Bme680CalibrationData();
- _controlRegister = (byte)Bme680Register.CTRL_MEAS;
- break;
- default:
- throw new Exception("Bmxx80 device not correctly configured. Could not find calibraton data.");
- }
- _calibrationData.ReadFromDevice(this);
- }
实际的代码中使用了条件编译。因为项目是多目标的,并且.NET 5.0+仅支持此属性。使用该属性可以跳过运行时检查(在构造函数中)。
7. 应用部署
编写或更新应用程序后,需要对其进行以使用户受益。这可能是到Web服务器,云服务或客户端计算机的,并且可能是使用Azure DevOps或GitHub Actions之类的服务的CI/CD流的结果。
.NET 5.0,专注于改进单个文件应用程序,减小docker多阶段构建的容器大小,并为使用.NET Core部署ClickOnce应用程序提供更好的支持。
8. 容器
容器是最重要的云趋势,.NET软件堆栈的多个级别以多种方式对容器进行支持。首先是在基础方面的支持,这越来越受到容器方案和部署容器化应用程序的开发人员的影响。
为和容器协调器的合作变得更加容易。添加了OpenTelemetry支持,以便可以从应用程序中捕获分布式跟踪和指标。dotnet-monitor是一个新工具,旨在作为从.NET进程访问诊断信息的主要方法。特别是,已经开始构建dotnet-monitor的容器变体,可以将其用作应用程序sidecar。还在构建dotnet/tye,以提高微服务开发人员在开发和部署到Kubernetes环境中的生产率。
.NET运行时现在支持cgroup v2,预计它将在2020年以后成为与容器相关的重要API。Docker当前使用cgroup v1(.NET已经支持)。相比之下,cgroup v2比cgroup v1更简单,更高效,更安全。Linux发行版和容器运行时正在。一旦变得更常见,.NET 5.0将在cgroup v2环境中正常工作。
除了Nano Server,还将发布Windows Server Core镜像。该镜像支持以下组合:Windows Server 2019长期服务通道(LTSC)、. NET 5.0和x64。还有其他更改,以减小Windows Server Core镜像的大小。
作为使用" .NET"作为产品名称的一部分,现在将.NET Core 2.1、3.1和.NET 5.0镜像发布到repos系列。同.NET Core 2.1和3.1一起发布,同时支持多版本。.NET 5.0镜像将发布到新位置。请相应地更新您的语句和脚本。
作为.NET 5.0的一部分,将SDK映像重新建立在ASP.NET镜像之上,而不是buildpack-deps,以显著减小在多阶段构建方案中提取的聚合映像的大小。
Ubuntu 20.04 Focal 多阶段构建成本:
下载节省量:100 MB(-30%)
Debian 10 Buster 多阶段构建成本:
净下载节省量:146 MB(-40%)
对Alpine和Nano Server进行了类似的更改。Alpine或Nano Server没有任何buildpack-depssdk镜像。对于多阶段构建,将看到Alpine和Nano Server以及5.0的巨大成功。
9. 单文件应用
单个文件应用程序作为单个文件发布和部署。该应用程序及其依赖项都包含在该文件中。当应用程序运行时,依赖项直接从该文件加载到内存中(不影响性能)。
在.NET 5.0中,单个文件应用程序主要集中在Linux上(稍后再介绍)。它们可以是框架相关的,也可以是独立的。依赖于全局安装的.NET运行时,依赖于框架的单个文件应用程序可能很小。自包含的单文件应用程序较大(由于带有运行时),但不需要作为安装前步骤就安装.NET运行时,因此可以正常工作。通常,依赖框架对开发和企业环境有利,而对于ISV,独立包含通常是更好的选择。
在所有平台上,都有一个名为" apphost"的组件。这是成为可执行文件的文件,例如在Windows上或myapp.exe./myapp在基于Unix的平台上。对于单文件应用程序,创建了一个新的应用程序主机"超级主机"。它具有与常规apphost相同的角色,但还包含运行时的静态链接副本。超级主机是单文件方法的基本设计点。该模型是在带有.NET 5.0的Linux上使用的模型。由于各种操作系统限制,无法在Windows或macOS上实现此方法。在Windows或macOS上没有超级主机。在这些操作系统上,本机运行时二进制文件(约3个)位于单个文件应用程序旁边(导致"不是单个文件")。
框架相关的单文件应用程序:
- dotnet publish -r linux-x64 --self-contained false /p:PublishSingleFile=true
自包含的单文件应用程序:
- dotnet publish -r linux-x64 --self-contained true /p:PublishSingleFile=true
还可以使用项目文件配置单个文件发布。
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- <!-- The OS and CPU type you are targeting -->
- <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
- <!-- Determine self-contained or framework-dependent -->
- <SelfContained>true</SelfContained>
- <!-- Enable single file -->
- <PublishSingleFile>true</PublishSingleFile>
- </PropertyGroup>
- </Project>
10. ClickOnce
ClickOnce一直是流行的.NET部署选项。.NET Core 3.1和.NET 5.0 Windows应用程序现在支持它。在.NET Core 3.0添加Windows Forms和WPF支持时,许多人会希望使用ClickOnce进行应用程序部署。在过去的一年中,.NET和Visual Studio团队共同努力,以在命令行和Visual Studio中启用ClickOnce发布:
目前支持的主要部署模型是框架相关的应用程序。对.NET桌面运行时(即包含WPF和Windows窗体的运行时)的依赖很容易。
Mage的最大变化是它现在是在NuGet上分发的.NET工具。这意味着不需要在计算机上安装任何特殊的东西,只需要.NET 5.0 SDK就可以将Mage安装为.NET工具。也可以使用它来发布.NET Framework应用程序,但是,SHA1签名和部分信任支持已被删除。Mage安装命令如下:
- dotnet tool install -g Microsoft.DotNet.Mage
制作并分发ClickOnce安装程序后,用户将看到熟悉的ClickOnce安装对话框。
二、工具改善
新改进了Windows窗体设计器,更改了目标框架适用于.NET 5.0及更高版本的方式,更改了WinRT的支持方式,并进行了其他改进。
1. Windows窗体设计器
Windows Forms设计器(用于.NET Core 3.1和.NET 5.0)已经在Visual Studio 16.8中进行了更新,现在支持所有Windows Forms控件。它还支持WinForms控件的Telerik UI。设计器包括期望的所有设计器功能,包括:拖放,选择,移动和调整大小,剪切/复制/粘贴/删除控件,与属性窗口集成,事件生成等。数据绑定和对更广泛的第三方控件的支持即将推出。
2. .NET 5.0目标框架
新版本更改了用于目标框架的方法。以下项目文件演示了新的.NET 5.0目标框架。
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- </PropertyGroup>
- </Project>
到目前为止,新表单比目前使用的样式更紧凑,更直观。另外,正在扩展目标框架以描述操作系统依赖性。
Windows桌面API(包括Windows窗体,WPF和WinRT)仅在net5.0-windows可用。可以指定操作系统版本,例如net5.0-windows7或net5.0-windows10.0.17763.0。如果要使用WinRT API,则需要为Windows 10版本。
使用新的net5.0-windows TFM时,跨平台方案可能会更具挑战性。如果您要避免为Windows构建或避免在Linux上提取Windows运行时程序包,
3. WinRT Interop(重大更改)
Windows API主题上,已移至一个新模型,以作为.NET 5.0的一部分来支持WinRT API。包括调用API(在任一方向上;CLR <==> WinRT),两个类型系统之间的数据封送处理以及打算在类型系统或ABI边界上统一对待。
在.NET 5.0中现有的WinRT互操作体系已被去除,这是一个巨大的变化。这意味着使用WinRT和.NET Core 3.x的应用程序和库将需要重建,并且不能按原样在.NET 5.0上运行。使用WinRT API的库将需要多目标来管理.NET Core 3.1和.NET 5.0之间的这种差异。
未来,将依靠Windows中的WinRT团队提供的新CsWinRT工具。它生成基于C#的WinRT互操作程序集,可以通过NuGet交付该程序集。Windows团队正是针对Windows中的WinRT API所做的。希望将WinRT(在Windows上)用作互操作系统的任何人都可以使用该工具,以将本机API公开给.NET或将.NET API公开给本机代码。
CsWinRT工具在逻辑上类似于TLBIMP和tlbexp,虽然好多了。tlb工具依赖于.NET运行时中的许多COM互操作管道。CsWinRT工具仅依赖于公共.NET API。就是说,C#9中的函数指针功能(部分在.NET 5.0运行时中实现)在某种程度上受到CsWinRT工具需求的启发。
这种新的WinRT互操作模型有几个好处:
- 可以独立于.NET运行时进行开发和改进。
- 它与为其他操作系统(如iOS和Android)提供的基于工具的互操作系统对称。
- 该工具可以利用其他.NET功能(AOT,C#功能,IL链接),而以前的系统则不提供该功能。
- 简化.NET运行时代码库。
- 无需添加NuGet引用即可使用WinRT API。对于indows 10 TFM(在前面的.NET 5.0 TFM部分中已经讨论过)就足够了。如果目标是.NET Core 3.1或更早版本,则需要引用WinRT软件包。
4. 本机导出
已经为导出本机二进制文件启用导出,而本机二进制文件在很长一段时间内都已调用.NET代码。该方案的构建块是对UnmanagedCallersOnlyAttribute的。
.NET Native导出项目支持:
- 公开自定义的本地出口。
- 不需要像COM这样的高级互操作技术。
- 跨平台工作。
5. 事件管道
事件管道是在.NET Core 2.2中添加的新的系统和API,可以在任何操作系统上执行性能和其他诊断调查。在.NET 5.0中,事件管道已得到扩展,以使事件探查器能够写入事件管道事件。对于以前依靠ETW(在Windows上)监视应用程序行为和性能的分析探查器,此方案至关重要。
新版本中可以通过事件管道获得程序集加载信息。这项改进是开始提供类似的诊断功能(作为.NET Framework的一部分)的开始,例如。现在,可以使用通过以下命令来收集此信息:
- dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4:4 -- ./MyApp –my-arg 1
工作流在dotnet-trace docs中进行了描述。可以查看简单测试应用程序的程序集加载信息。
6. Microsoft.Extensions.Logging
Microsoft.Extensions.Logging库中的控制台日志提供程序进行了改进。可以通过ConsoleFormatter自定义对控制台输出的格式和颜色进行完全控制。格式化程序API通过实现VT-100(大多数现代终端支持的)转义序列的子集来实现丰富的格式化。控制台记录器可以解析不受支持的终端上的转义序列,使您可以为所有终端编写单个格式化程序。
除了支持自定义格式器外,还添加了内置的JSON格式器,该格式器向控制台发出结构化JSON日志。
7. Dump调试
调试托管代码需要了解托管对象和构造。数据访问组件(DAC)是运行时执行引擎的子集,该引擎具有这些构造的知识,并且可以在没有运行时的情况下访问这些托管对象。现在,可以使用WinDBG或dotnet dump analyze在Windows上分析在Linux上收集的.NET Core进程dump。
还添加了对从macOS上运行的.NET进程捕获ELF dump的支持。由于ELF不是macOS上的本机可执行文件(像lldb这样的本地调试器将无法与这些dump一起使用)文件格式,因此将其设为选择加入功能。要在macOS上支持收集,请设置环境变量COMPlus_DbgEnableElfDumpOnMacOS=1。可以使用dotnet dump analyze来分析产生的dump。
8. 打印环境信息
随着.NET扩展了对新操作系统和芯片体系结构的支持,有时需要一种打印环境信息的方法。.NET5创建了一个简单的.NET工具dotnet-runtimeinfo来执行该操作。
可以使用以下命令安装和运行该工具。
- dotnet tool install -f dotnet-runtimeinfo
- dotnet-runtimeinfo
该工具以可以生成诸如如下格式的环境信息。
- **.NET information
- Version: 5.0.0
- FrameworkDescription: .NET 5.0.0
- Libraries version: 5.0.0
- Libraries hash: cf258a14b70ad9069470a108f13765e0e5988f51
- **Environment information
- OSDescription: Linux 5.8.6-1-MANJARO-ARM #1 SMP Thu Sep 3 22:01:08 CEST 2020
- OSVersion: Unix 5.8.6.1
- OSArchitecture: Arm64
- ProcessorCount: 6
- **CGroup info**
- cfs_quota_us: -1
- memory.limit_in_bytes: 9223372036854771712
- memory.usage_in_bytes: 2740666368
其他更新
1. Windows Arm64
.NET应用程序现在可以在Windows Arm64上本机运行。这是在.NET Core 3.0中添加的对Linux Arm64的支持(对glibc和musl的支持)。
在.NET 5.0中,可以在Windows Arm64设备(例如Surface Pro X)上开发和运行应用程序。已经可以通过x86仿真在Windows Arm64上运行.NET Core和.NET Framework应用程序。这是可行的,但是本机Arm64执行具有更好的性能。
用于Arm64的MSI安装程序是此版本的最终更改之一。下面是.NET 5.0 SDK安装程序。
Windows Arm64上支持SDK,控制台和ASP.NET Core应用程序,但Windows桌面组件暂不支持。
2. Windows上支持ICU
ICU库用于Unicode和全球化支持,以前仅在Linux和macOS上使用。现在在Windows 10上使用相同的库。此更改使全球化API的行为(如特定文化区域的字符串比较)在Windows 10,macOS和Linux之间保持一致。还将ICU与Blazor WebAssembly支持一起使用。
3. System.Text.Json
在.NET 5.0中已进行了显著改善,在性能,可靠性,并使熟悉Newtonsoft.Json的人们更容易采用。它还包括对将JSON对象反序列化为记录的支持。
使更新可用时,用户将看到更新对话框。
三、总结
.NET 5.0是另一个重要版本发布,它改善.NET使用的许多方面。已经实现了从单文件应用程序到性能,从Json序列化可用性到Arm64支持的一系列广泛改进。C#9和F#5中的新语言改进将使代码更具表现力,更易于编写。.NET 5.0也是现有应用程序的绝佳选择,在许多情况下,可以轻松进行升级。