![11378c50588fc3a805b85ae2050b5818.png](https://i-blog.csdnimg.cn/blog_migrate/c362e01bff23be8f4e14a229b1fddecd.jpeg)
今日是一年一度光棍节,首先祝各位码农朋友们节日快乐,在关注技术的同时也要同时关注另一半,争取早日脱单,今天不过节,只专心于技术!
今天微软开发团队宣布发布.NET 5.0正式版。主要更新包括C#9和F#5在内的一系列新功能和改进。同期发布了ASP.NET Core,EF Core,C#9和F#5。可以在官方下载页面下载跨平台包括Windows,macOS和Linux和跨处理架构包括x86,x64,Arm32,Arm64。
![41ee84b48975d35dbadf841c2d9aa63d.png](https://i-blog.csdnimg.cn/blog_migrate/b89a4b595f858803c21195d0ae5dfaf0.jpeg)
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扩展了平台范围。
跨平台和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使用完全相同的代码。
语言功能
作为.NET 5.0版本的一部分,C#9和F#5被包含在.NET 5.0 SDK中。Visual SDK也包含在5.0 SDK中。它不包括语言更改,但做了改进以支持.NET Core上的Visual Basic应用程序框架。
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 offwhile (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编程还可能更加复杂。
逻辑和属性模式
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));}
记录
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);
可空断言改进
.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+仅支持此属性。使用该属性可以跳过运行时检查(在构造函数中)。
应用部署
编写或更新应用程序后,需要对其进行以使用户受益。这可能是到Web服务器,云服务或客户端计算机的,并且可能是使用Azure DevOps或GitHub Actions之类的服务的CI/CD流的结果。
.NET 5.0,专注于改进单个文件应用程序,减小docker多阶段构建的容器大小,并为使用.NET Core部署ClickOnce应用程序提供更好的支持。
容器
容器是最重要的云趋势,.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 多阶段构建成本:
![e3d368091e3ecb726479f7477ff3d4d1.png](https://i-blog.csdnimg.cn/blog_migrate/40bf2348e54359bf5566568e717fdb63.jpeg)
下载节省量:100 MB(-30%)
Debian 10 Buster 多阶段构建成本:
![eace2068e95f82db91c125f63141ced9.png](https://i-blog.csdnimg.cn/blog_migrate/79e36a080820b92d0e4389fc0d2ee65e.jpeg)
净下载节省量:146 MB(-40%)
对Alpine和Nano Server进行了类似的更改。Alpine或Nano Server没有任何buildpack-depssdk镜像。对于多阶段构建,将看到Alpine和Nano Server以及5.0的巨大成功。
单文件应用
单个文件应用程序作为单个文件发布和部署。该应用程序及其依赖项都包含在该文件中。当应用程序运行时,依赖项直接从该文件加载到内存中(不影响性能)。
在.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
还可以使用项目文件配置单个文件发布。
Exenet5.0linux-x64truetrue
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发布:
![349ad4d57a7c782b34ca1eb7c791f9cb.png](https://i-blog.csdnimg.cn/blog_migrate/352fa732e457e7801ce243a41a51e45d.jpeg)
目前支持的主要部署模型是框架相关的应用程序。对.NET桌面运行时(即包含WPF和Windows窗体的运行时)的依赖很容易。
![6cd4aadcc9ee947acf4f22760b4f5c17.png](https://i-blog.csdnimg.cn/blog_migrate/757259a16b699ac6f6a628592e4b11df.jpeg)
![af61193771cc38e3e0391870a560aed4.png](https://i-blog.csdnimg.cn/blog_migrate/b79367fd3efa7cd1cb50172823d83e0d.jpeg)
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的支持方式,并进行了其他改进。
Windows窗体设计器
Windows Forms设计器(用于.NET Core 3.1和.NET 5.0)已经在Visual Studio 16.8中进行了更新,现在支持所有Windows Forms控件。它还支持WinForms控件的Telerik UI。设计器包括期望的所有设计器功能,包括:拖放,选择,移动和调整大小,剪切/复制/粘贴/删除控件,与属性窗口集成,事件生成等。数据绑定和对更广泛的第三方控件的支持即将推出。
![d00d342d00688a0392716d25c6b7d72b.png](https://i-blog.csdnimg.cn/blog_migrate/8730347666b02c17a58fc123ef9c4f9e.jpeg)
.NET 5.0目标框架
新版本更改了用于目标框架的方法。以下项目文件演示了新的.NET 5.0目标框架。
Exenet5.0
到目前为止,新表单比目前使用的样式更紧凑,更直观。另外,正在扩展目标框架以描述操作系统依赖性。
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运行时程序包,
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软件包。
本机导出
已经为导出本机二进制文件启用导出,而本机二进制文件在很长一段时间内都已调用.NET代码。该方案的构建块是对UnmanagedCallersOnlyAttribute的。
.NET Native导出项目支持:
公开自定义的本地出口。
不需要像COM这样的高级互操作技术。
跨平台工作。
事件管道
事件管道是在.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中进行了描述。可以查看简单测试应用程序的程序集加载信息。
![c48c4a60ae8ec475af7a0959ea7a2018.png](https://i-blog.csdnimg.cn/blog_migrate/a08f44d448280469c323106217df639f.jpeg)
Microsoft.Extensions.Logging
Microsoft.Extensions.Logging库中的控制台日志提供程序进行了改进。可以通过ConsoleFormatter自定义对控制台输出的格式和颜色进行完全控制。格式化程序API通过实现VT-100(大多数现代终端支持的)转义序列的子集来实现丰富的格式化。控制台记录器可以解析不受支持的终端上的转义序列,使您可以为所有终端编写单个格式化程序。
除了支持自定义格式器外,还添加了内置的JSON格式器,该格式器向控制台发出结构化JSON日志。
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。
打印环境信息
随着.NET扩展了对新操作系统和芯片体系结构的支持,有时需要一种打印环境信息的方法。.NET5创建了一个简单的.NET工具dotnet-runtimeinfo来执行该操作。
可以使用以下命令安装和运行该工具。
dotnet tool install -f dotnet-runtimeinfodotnet-runtimeinfo
该工具以可以生成诸如如下格式的环境信息。
**.NET informationVersion: 5.0.0FrameworkDescription: .NET 5.0.0Libraries version: 5.0.0Libraries hash: cf258a14b70ad9069470a108f13765e0e5988f51**Environment informationOSDescription: Linux 5.8.6-1-MANJARO-ARM #1 SMP Thu Sep 3 22:01:08 CEST 2020OSVersion: Unix 5.8.6.1OSArchitecture: Arm64ProcessorCount: 6**CGroup info**cfs_quota_us: -1memory.limit_in_bytes: 9223372036854771712memory.usage_in_bytes: 2740666368
其他更新
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安装程序。
![981a93e18e56caddd618df61991e33f4.png](https://i-blog.csdnimg.cn/blog_migrate/e995dc2d0fbb5b940fa983e9a70f6c90.jpeg)
Windows Arm64上支持SDK,控制台和ASP.NET Core应用程序,但Windows桌面组件暂不支持。
Windows上支持ICU
ICU库用于Unicode和全球化支持,以前仅在Linux和macOS上使用。现在在Windows 10上使用相同的库。此更改使全球化API的行为(如特定文化区域的字符串比较)在Windows 10,macOS和Linux之间保持一致。还将ICU与Blazor WebAssembly支持一起使用。
System.Text.Json
在.NET 5.0中已进行了显著改善,在性能,可靠性,并使熟悉Newtonsoft.Json的人们更容易采用。它还包括对将JSON对象反序列化为记录的支持。
![08609b0f4e3a3f720e508a635a3e9abd.png](https://i-blog.csdnimg.cn/blog_migrate/e3967815c3fc808b96bf35ef67da5e24.jpeg)
使更新可用时,用户将看到更新对话框。
![298f9c96623f77a359443416b6f3c161.png](https://i-blog.csdnimg.cn/blog_migrate/ff3e1d90811388c3cedd9798b5694703.jpeg)
总结
.NET 5.0是另一个重要版本发布,它改善.NET使用的许多方面。已经实现了从单文件应用程序到性能,从Json序列化可用性到Arm64支持的一系列广泛改进。C#9和F#5中的新语言改进将使代码更具表现力,更易于编写。.NET 5.0也是现有应用程序的绝佳选择,在许多情况下,可以轻松进行升级。