.NET 6 史上最全攻略

本文详细介绍了.NET 6 的主要改进和新特性,包括性能大幅提升,如动态PGO优化、文件IO性能增强、接口检查和转换速度加快;C# 10 的新功能,如全局using指令、文件范围的命名空间、记录结构;F# 6 的性能改进和易用性提升;以及源代码生成器、Hot Reload、统一扩展平台、安全性和Arm64支持等方面的增强。此外,文章还讨论了.NET 6的长期支持、跨平台统一平台、性能基准测试和新API等。
摘要由CSDN通过智能技术生成

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
欢迎使用.NET 6。今天的版本是.NET 团队和社区一年多努力的结果。C# 10 和F# 6 提供了语言改进,使您的代码更简单、更好。性能大幅提升,我们已经看到微软降低了托管云服务的成本。.NET 6 是第一个原生支持Apple Silicon (Arm64) 的版本,并且还针对Windows Arm64 进行了改进。我们构建了一个新的动态配置文件引导优化(PGO) 系统,该系统可提供仅在运行时才可能进行的深度优化。使用dotnet monitorOpenTelemetry改进了云诊断。WebAssembly支持更有能力和性能。HTTP/3添加了新的API ,处理JSON数学和直接操作内存。.NET 6 将支持三年。开发人员已经开始将应用程序升级到.NET 6,我们在生产中听到了很好的早期成果。.NET 6 已为您的应用程序做好准备。

您可以下载适用于Linux、macOS 和Windows 的.NET 6 。

请参阅ASP.NET CoreEntity FrameworkWindows Forms.NET MAUIYARPdotnet 监视器帖子,了解各种场景中的新增功能。

.NET 6 亮点

.NET 6 是:

该版本包括大约一万次git 提交。即使这篇文章很长,它也跳过了许多改进。您必须下载并试用.NET 6 才能看到所有新功能。

支持

.NET 6 是一个长期支持(LTS) 版本,将支持三年。它支持多种操作系统,包括macOS Apple Silicon 和Windows Arm64。

Red Hat与.NET 团队合作,在Red Hat Enterprise Linux 上支持.NET。在RHEL 8 及更高版本上,.NET 6 将可用于AMD 和Intel (x64_64)、ARM (aarch64) 以及IBM Z 和LinuxONE (s390x) 架构。

请开始将您的应用程序迁移到.NET 6,尤其是.NET 5 应用程序。我们从早期采用者那里听说,从.NET Core 3.1 和.NET 5 升级到.NET 6 很简单。

Visual Studio 2022Visual Studio 2022 for Mac支持.NET 6 。Visual Studio 2019、Visual Studio for Mac 8 或MSBuild 16 不支持它。如果要使用.NET 6,则需要升级到Visual Studio 2022(现在也是64 位)。Visual Studio Code C# 扩展支持.NET 6 。

Azure App 服务:

注意:如果您的应用已经在应用服务上运行.NET 6 预览版或RC 版本,则在将.NET 6 运行时和SDK 部署到您所在区域后,它将在第一次重新启动时自动更新。如果您部署了一个独立的应用程序,您将需要重新构建和重新部署。

统一扩展平台

.NET 6 为浏览器桌面物联网移动应用程序提供了一个统一的平台。底层平台已更新,可满足所有应用类型的需求,并便于在所有应用中重用代码。新功能和改进同时适用于所有应用程序,因此您在云或移动设备上运行的代码的行为方式相同并具有相同的优势。

.NET 开发人员的范围随着每个版本的发布而不断扩大。机器学习WebAssembly是最近添加的两个。例如,通过机器学习,您可以编写在流数据中查找异常的应用程序。使用WebAssembly,您可以在浏览器中托管.NET 应用程序,就像HTML 和JavaScript 一样,或者将它们与HTML 和JavaScript 混合使用

最令人兴奋的新增功能之一是.NET Multi-platform App UI (.NET MAUI)。您现在可以在单个项目中编写代码,从而跨桌面和移动操作系统提供现代客户端应用程序体验。.NET MAUI 将比.NET 6 稍晚发布。我们在.NET MAUI 上投入了大量时间和精力,很高兴能够发布它并看到.NET MAUI 应用程序投入生产。

当然,.NET 应用程序也可以在家中使用Windows 桌面(使用Windows FormsWPF)以及使用ASP.NET Core 在云中。它们是我们提供时间最长的应用程序类型,并且仍然非常受欢迎,我们在.NET 6 中对其进行了改进。

面向 .NET 6

继续以广泛平台为主题,在所有这些操作系统上编写.NET 代码很容易。

以 .NET 6 为目标,您需要使用.NET 6 目标框架,如下所示:

net6.0

net6.0 Target Framework Moniker (TFM) 使您可以访问.NET 提供的所有跨平台API。如果您正在编写控制台应用程序、ASP.NET Core 应用程序或可重用的跨平台库,这是最佳选择。

如果您针对特定操作系统(例如编写Windows 窗体或iOS 应用程序),那么还有另一组TFM(每个都针对不言而喻的操作系统)供您使用。它们使您可以访问所有net6.0的API以及一堆特定于操作系统的API。

  • net6.0-android
  • net6.0-ios
  • net6.0-maccatalyst
  • net6.0-tvos
  • net6.0-windows

每个无版本TFM 都相当于针对.NET 6 支持的最低操作系统版本。如果您想要具体或访问更新的API,可以指定操作系统版本。

net6.0和net6.0-windows TFMs 都支持(与.NET 5 相同)。Android 和Apple TFM 是.NET 6 的新功能,目前处于预览阶段。稍后的.NET 6 更新将支持它们。

操作系统特定的 TFM 之间没有兼容性关系。 例如,net6.0-ios与 net6.0-tvos不兼容。 如果您想共享代码,您需要使用带有#if 语句的源代码或带有net6.0目标代码的二进制文件来实现。

性能

自从我们启动.NET Core 项目以来,该团队一直在不断地关注性能。Stephen Toub在记录每个版本的.NET 性能进展方面做得非常出色。欢迎查看.NET 6 中的性能改进的帖子。在这篇文章中,里面包括您想了解的重大性能改进,包括文件IO、接口转换、PGO 和System.Text.Json。

动态 PGO

**动态轮廓引导优化(PGO)**可以显着提高稳态性能。例如,PGO 为TechEmpower JSON"MVC"套件的每秒请求数提高了26%(510K -> 640K)。

动态PGO 建立在分层编译的基础上,它使方法能够首先非常快速地编译(称为"第0 层")以提高启动性能,然后在启用大量优化的情况下随后重新编译(称为"第1 层")一旦该方法被证明是有影响的。该模型使方法能够在第0 层中进行检测,以允许对代码的执行进行各种观察。在第1 层重新调整这些方法时,从第0 层执行收集的信息用于更好地优化第1 层代码。这就是机制的本质。

动态PGO 的启动时间将比默认运行时稍慢,因为在第0 层方法中运行了额外的代码来观察方法行为。

要启用动态 PGO,请在应用程序将运行的环境中设置 DOTNET_TieredPGO=1。 您还必须确保启用分层编译(默认情况下)。 动态 PGO 是可选的,因为它是一种新的且有影响力的技术。 我们希望发布选择加入使用和相关反馈,以确保它经过全面压力测试。 我们对分层编译做了同样的事情。 至少一个非常大的 Microsoft 服务支持并已在生产中使用动态 PGO。 我们鼓励您尝试一下。

您可以在.NET 6中的性能帖子中看到更多关于动态PGO 优势的信息,包括以下微基准,它测量特定LINQ 枚举器的成本。

private IEnumerator<long> _source = Enumerable.Range(0, long.MaxValue).GetEnumerator();

[Benchmark]
public void MoveNext() => _source.MoveNext();

这是有和没有动态PGO 的结果。

方法 意思是 代码大小
PGO 已禁用 1.905 纳秒 30乙
启用PGO 0.7071 纳秒 105乙

这是一个相当大的差异,但代码大小也有所增加,这可能会让一些读者感到惊讶。这是由JIT 生成的汇编代码的大小,而不是内存分配(这是一个更常见的焦点)。.NET 6 性能帖子对此有很好的解释。

PGO 实现中常见的一种优化是"热/冷分离",其中经常执行的方法部分(“热”)在方法开始时靠近在一起,而不经常执行的方法部分(“冷”)是移到方法的末尾。这样可以更好地使用指令缓存,并最大限度地减少可能未使用的代码负载。

作为上下文,接口调度是 .NET 中最昂贵的调用类型。 非虚拟方法调用是最快的,甚至更快的是可以通过内联消除的调用。 在这种情况下,动态 PGO 为 MoveNext 提供了两个(替代)调用站点。 第一个 - 热的 - 是对 Enumerable+RangeIterator.MoveNext的直接调用,另一个 - 冷的 - 是通过 IEnumerator的虚拟接口调用。 如果大多数时候最热门的人都被叫到,那将是一个巨大的胜利。

这就是魔法。当 JIT 检测此方法的第 0 层代码时,包括检测此接口调度以跟踪每次调用时 \_source的具体类型。 JIT 发现每次调用都在一个名为 Enumerable+RangeIterator的类型上,这是一个私有类,用于在 Enumerable实现内部实现 Enumerable.Range。因此,对于第 1 层,JIT 已发出检查以查看 \_source的类型是否为 Enumerable+RangeIterator:如果不是,则跳转到我们之前强调的执行正常接口调度的冷部分。但如果是 - 基于分析数据,预计绝大多数时间都是这种情况 - 然后它可以继续直接调用非虚拟化的 Enumerable+RangeIterator.MoveNext方法。不仅如此,它还认为内联 MoveNext 方法是有利可图的。最终效果是生成的汇编代码有点大,但针对预期最常见的确切场景进行了优化。当我们开始构建动态 PGO 时,这些就是我们想要的那种胜利。

动态PGO 将在RyuJIT 部分再次讨论。

文件 IO 改进

FileStream几乎完全用.NET 6 重写,重点是提高异步文件IO 性能。在Windows 上,实现不再使用阻塞API,并且可以 快几倍 !我们还改进了所有平台上的内存使用。在第一次异步操作(通常分配)之后,我们已经使异步操作 免分配 !此外,我们已经使Windows 和Unix 实现不同的边缘情况的行为统一(这是可能的)。

这种重写的性能改进使所有操作系统受益。对Windows 的好处是最大的,因为它远远落后。macOS 和Linux 用户也应该会看到显着FileStream的性能改进。

以下基准将100 MB 写入新文件。

private byte[] _bytes = new byte[8_000];

[Benchmark]
public async Task Write100MBAsync()
{
    using FileStream fs = new("file.txt", FileMode.Create, FileAccess.Write, FileShare.None, 1, FileOptions.Asynchronous);
    for (int i = 0; i < 100_000_000 / 8_000; i++)
        await fs.WriteAsync(_bytes);
}

在带有SSD 驱动器的Windows 上,我们观察到 4倍的加速 和超过 1200倍的分配下降

方法 运行 意思是 比率 已分配
写100MBAsync .NET 5.0 1,308.2 毫秒 1.00 3,809 KB
写100MBAsync .NET 6.0 306.8 毫秒 0.24 3 KB

我们还认识到需要更高性能的文件 IO 功能:并发读取和写入,以及分散/收集 IO。 针对这些情况,我们为 System.IO.FileSystem.IO.RandomAccess类引入了新的 API。

async Task AllOrNothingAsync(string path, IReadOnlyListbyte>> buffers)
{
    using SafeFileHandle handle = File.OpenHandle(
        path, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.Asynchronous,
        preallocationSize: buffers.Sum(buffer => buffer.Length)); // hint for the OS to pre-allocate disk space

    await RandomAccess.WriteAsync(handle, buffers, fileOffset: 0); // on Linux it's translated to a single sys-call!

该示例演示:

预分配大小功能提高了性能,因为写入操作不需要扩展文件,并且文件不太可能被碎片化。这种方法提高了可靠性,因为写入操作将不再因空间不足而失败,因为空间已被保留。Scatter/Gather IO API 减少了写入数据所需的系统调用次数。

更快的接口检查和转换

界面铸造性能提高了16% - 38%。这种改进对于C# 与接口之间的模式匹配特别有用。

这张图表展示了一个有代表性的基准测试的改进规模。

将.NET 运行时的一部分从C++ 迁移到托管C# 的最大优势之一是它降低了贡献的障碍。这包括接口转换,它作为早期的.NET 6 更改移至C#。.NET 生态系统中懂C# 的人比懂C++ 的人多(而且运行时使用具有挑战性的C++ 模式)。仅仅能够阅读构成运行时的一些代码是培养以各种形式做出贡献的信心的重要一步。

归功于 Ben Adams

System.Text.Json 源生成器

我们为System.Text.Json 添加了一个源代码生成器,它避免了在运行时进行反射和代码生成的需要,并且可以在构建时生成最佳序列化代码。序列化程序通常使用非常保守的技术编写,因为它们必须如此。但是,如果您阅读自己的序列化源代码(使用序列化程序),您可以看到明显的选择应该是什么,可以使序列化程序在您的特定情况下更加优化。这正是这个新的源生成器所做的。

除了提高性能和减少内存之外,源代码生成器还生成最适合装配修整的代码。这有助于制作更小的应用程序。

序列化POCO是一种非常常见的场景。使用新的源代码生成器,我们观察到序列化速度比我们的基准 快1.6倍

方法 意思是 标准差 比率
串行器 243.1 纳秒 9.54 纳秒 1.00
SrcGenSerializer 149.3 纳秒 1.91 纳秒 0.62

TechEmpower缓存基准测试平台或框架对来自数据库的信息进行内存缓存。基准测试的.NET 实现执行缓存数据的JSON 序列化,以便将其作为响应发送到测试工具。

请求** / ** 要求
net5.0 243,000 3,669,151
网6.0 260,928 3,939,804
net6.0 + JSON 源码生成 364,224 5,499,468

我们观察到约100K RPS 增益( 增加约40%)。与 MemoryCache 性能改进相结合时,.NET 6 的吞吐量比.NET 5 高50% !

C# 10

欢迎来到C# 10。C# 10 的一个主要主题是继续从C# 9 中的顶级语句开始的简化之旅。新功能从 Program.cs中删除了更多的仪式,导致程序只有一行。 他们的灵感来自于与没有 C# 经验的人(学生、专业开发人员和其他人)交谈,并了解什么对他们来说最有效且最直观。

大多数.NET SDK 模板都已更新,以提供现在可以使用C# 10 实现的更简单、更简洁的体验。我们收到反馈说,有些人不喜欢新模板,因为它们不适合专家,删除面向对象,删除在编写C# 的第一天学习的重要概念,或鼓励在一个文件中编写整个程序。客观地说,这些观点都不正确。新模型同样适用于作为专业开发人员的学生。但是,它与.NET 6 之前的C 派生模型不同。

C# 10 中还有其他一些功能和改进,包括记录结构。

全局使用指令

全局using 指令让您using只需指定一次指令并将其应用于您编译的每个文件。

以下示例显示了语法的广度:

  • global using System;
  • global using static System.Console;
  • global using Env = System.Environment;

您可以将global using语句放在任何 .cs 文件中,包括在 Program.cs中。

隐式 usings 是一个MSBuild 概念,它会根据SDK自动添加一组指令。例如,控制台应用程序隐式使用不同于ASP.NET Core。

隐式使用是可选的,并在a 中启用PropertyGroup

隐式使用对于现有项目是可选的,但默认包含在新C# 项目中。有关详细信息,请参阅隐式使用

文件范围的命名空间

文件范围的命名空间使您能够声明整个文件的命名空间,而无需将剩余内容嵌套在{ ...}中. 只允许一个,并且必须在声明任何类型之前出现。

新语法是单个的一行&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值