今天是.NET的关键时刻。 随着.NET 2015 Preview 4的发布,我们正在踏上新的征程,同时对今天使用.NET的十亿以上客户保持坚定的承诺。
.NET 5是.NET的下一个版本和未来。 我们正在通过统一框架从云到桌面再到移动再到其他领域,继续统一.NET平台的过程。 回顾过去,我们充分利用了.NET Framework的优势,并将其放入.NET Core 3中,包括对WPF和Windows Forms的支持。 在我们继续前进的过程中,我们将移动Xamarin和.NET Web程序集以使用.NET 5库,并将dotnet工具扩展为在浏览器中定位移动和Web程序集。 同时,作为领先的云和容器运行时,我们将继续改进.NET功能。
您可以收听并收听Scott Hanselman和我在今天的“通往.NET的旅程”演讲中谈论.NET 5及更高版本 。
我们希望收到你的来信! 在https://aka.ms/dotnet5_feedback_blog上分享您对.NET 5的反馈。 我们非常重视您的反馈,并用它来帮助做出有关.NET未来的决策。
去年, 我们提出了.NET和.NET 5的愿景。我们说过,我们将采用.NET Core和Mono / Xamarin实现,并将它们统一为一个基类库(BCL)和工具链(SDK)。 在全球健康大流行之后,我们不得不适应客户不断变化的需求,并提供所需的支持以协助他们的平稳运营。 我们将继续努力帮助客户解决最紧急的需求。 因此,我们预计这些功能将在2020年11月之前提供预览,但是统一将通过我们的长期支持(LTS)版本.NET 6真正完成。 我们的愿景没有改变,但是我们的时间表已经改变。
我们仍然致力于一个.NET平台,并将在今年11月提供高质量的.NET 5版本。 您将继续看到一波创新浪潮,在通往.NET的过程中将进行多个预览。
下载预览4
您可以下载适用于Windows,macOS和Linux的.NET 5.0 Preview 4 :
https://dotnet.microsoft.com/download/dotnet/5.0
ASP.NET Core和EF Core也在今天发布。 PowerShell今天有一个基于.NET 5的发行版 ,现在按.NET时间表发行。
您需要Visual Studio 2019 16.6或更高版本才能使用.NET 5.0。 要将.NET 5.0与Visual Studio Code一起使用,请安装最新版本的C#扩展名 。 Mac的Visual Studio尚不支持.NET 5.0。
.NET 5.0 发行说明
https://github.com/dotnet/core/tree/master/release-notes/5.0/preview
让我们看一下我们预期将在11月随.NET 5提供的一些发行要点。 其中的许多更改都部分或全部包含在Preview 4中。这些亮点将为您在采用.NET 5时在开发过程和生产中可以利用的改进提供清晰的画面。
包括C#9和F#5。
性能—改善整个产品的性能 。
正则表达式:https://devblogs.microsoft.com/dotnet/regex-performance-improvements-in-net-5/
改善
string.ToUpperInvariant
,string.ToLowerInvariant
,char.ToUpperInvariant
,char.ToLowerInvariant
和其他相关模式的性能https://github.com/dotnet/runtime/pull/31968
改善HTTP 1.1性能
改善HTTP / 2性能
提高分层编译性能
提高堆栈序言归零性能
改善F#使用的尾调用的性能
一致的性能:我们更加注重可预测的一致性能,减少了性能偏差和离群值,重点是P95 +延迟。
改进分层JIT编译所使用的调用计数机制 ,以在启动过程中使性能变得平稳
内部通用字典的动态扩展 ,消除了通用代码造成的性能障碍
固定对象堆以减少由固定引起的堆碎片
在特定情况下,例如Array.Copy , Array.Sort或对象拆箱 ,减少GC暂停时间
单一文件应用程序-一种新的单一文件发布类型 ,可以从单个二进制文件中执行您的应用程序(例如,可以在只读媒体上使用)。
Windows ARM64 — 使.NET可以在Windows ARM64上本机运行 ,从而支持开发方案和在客户端计算机上部署客户端应用程序。
ARM64 —在JIT和BCL库中提高ARM64性能 (Linux和Windows)。
容器- 减小容器映像的大小并实现新的容器API,以使.NET能够与容器运行时的发展保持同步。
新的目标框架-我们为.NET TFM采用了新方法 。
JSON API —使从Newtonsoft.Json到System.Text.Json的迁移更加容易。
我将分享一些有关这些改进以及我们前进的方向的更详细的信息。
.NET 5.0目标框架
我们正在使用.NET 5.0更改用于目标框架的方法。 以下两个项目文件示例通过指定各自的目标框架Moniker(TFM)演示了.NET Core 3.1和.NET 5.0目标框架。 您会看到一个新的,更紧凑的.NET 5.0 TFM:
.NET Core 3.0:
< Project Sdk = “ Microsoft.NET.Sdk ” > < PropertyGroup > < OutputType > Exe OutputType > < TargetFramework > netcoreapp3.1 TargetFramework > PropertyGroup > Project >
.NET 5.0:
< Project Sdk = “ Microsoft.NET.Sdk ” > < PropertyGroup > < OutputType > Exe OutputType > < TargetFramework > net5.0 TargetFramework > PropertyGroup > Project >
我们对.NET 5.0的.NET TFM进行了几项重要更改,以简化它们的使用,减少概念并使其更易于公开特定于操作系统的API。
快速摘要:
随着.NET的发展,目标API版本将变得更加简单。 我们将没有两个TFM系列,例如: netcoreapp3.1
和netstandard2.0
。 相反,我们只有一个,如: net5.0
和net6.0
。 这是因为只有一个.NET实现在进行中,因此不再需要.NET Standard(这使库可以跨多个.NET产品兼容)。 您还可以定位操作系统API,对TFM进行少量扩展,例如net5.0-windows
和net6.0-android
。 我们还将从新的项目文件中删除不同的SDK,例如Sdk="Microsoft.NET.Sdk.WindowsDesktop"
,因为例如net5.0-windows
将提供相同的信息。 最大的胜利是,通过瞄准net5.0
,您可以访问100%的跨平台API,而不是.NET Standard中的子集。 使用哪个TFM总是很明显(它是可移植代码或特定于OS的),并且您无需等待Span<T>
类的API可用。
详细信息如下:
net5.0
是.NET 5.0的新目标框架Moniker(TFM)。net5.0
结合并替代了netcoreapp
和netstandard
TFM。net5.0
支持.NET Framework兼容模式net5.0-windows
将用于公开Windows特定的功能,例如Windows Forms和WPF。.NET 6.0将使用与
net6.0
相同的方法,并将添加net6.0-ios
和net6.0-android
。特定于操作系统的TFM可以包含操作系统版本号 ,例如
net6.0-ios14
。诸如ASP.NET Core和Xamarin.Forms之类的可移植框架将与
net5.0
一起使用。
这些变化是将.NET Core视为.NET的未来的结果 。 我们已经从产品的各个方面删除了“核心”名称,包括API和容器repos 。 通过删除.NET 5.0+的概念,我们也看到了进一步简化.NET的机会。 通过建立与.NET Framework和Xamarin的桥梁, .NET Standard在建立.NET Core中发挥了关键作用。 .NET Standard 2.0版本将保持相关性很多年,如果需要支持.NET Framework,我们建议您使用它。 对于不需要在.NET Framework上运行的应用程序和库,我们建议针对net5.0
TFM,这将使您能够访问最大的一组跨平台API。 对于Xamarin,.NET Standard 2.0和2.1仍然适用,但是,一旦Xamarin作为.NET 6.0的一部分集成到.NET中,则它将切换到net6.0
TFM,并且开发人员将专门针对.NET定位.NET Standard 2.0。框架兼容性。
您可能还想回答更多问题。 在发布.NET 5.0之前,我们将发布有关该主题的大型博客文章。 以下几点回答了一些最明显的剩余问题:
netcoreapp5.0
在较早的预览中使用,不再受支持,但是仍然有效。现有的.NET Standard版本将永远有效,并且支持它们的继续使用。
我们不希望创建任何新的
netstandard
版本。 .NET Standard 2.1可能是最新版本。没有计划使用
net5.0-linux
TFM,因为我们(尚未)公开任何特定于Linux的API。 另外,“ Linux”不是一个统一的数量,因此不清楚在此类TFM中将公开哪些API。 我们可以公开POSIX标准 ,但是我们将其称为net5.0-posix
,它可以在Linux以外的其他操作系统上运行。 但是,我们也没有任何计划。由于与Linux中所述类似的原因,我们不打算为Web组装公开TFM 。
您不能将.NET Framework项目中的
TargetFrameworkVersion
更新到5.0,并不能期望它成为.NET 5.0项目。 不起作用。 相反,您需要将应用程序移植到.NET Core 。 对于库,您可以移植到.NET Standard或.NET Core。 我们不再向.NET Core添加.NET Framework API ,因此无需等待将您的应用程序移植到.NET Core。新的TFM计划是工作量项目的基础部分。 我们将在.NET 5.0中添加对工作负载的最小支持,然后在.NET 6.0中实现完整的愿景。
用于.NET Core的Windows Forms Designer发布
今天我们很高兴地宣布,用于Visual Studio 2019版本16.6的预览版现已提供.NET Core项目的Windows窗体设计器! 我们还在Visual Studio 16.7预览版1中提供了更新的设计器版本!
要在Visual Studio中启用设计器,请转到“工具”>“选项”>“环境”>“预览功能”,然后选择“将Windows Forms预览设计器用于.NET Core应用程序”选项。
新的设计器支持所有Windows窗体控件,但DataGridView
和ToolStripContainer
除外(即将推出)。 它包含您期望的所有其他设计器功能,包括:拖放,选择,移动和调整大小,剪切/复制/粘贴/删除控件,与属性窗口集成,事件生成等。 数据绑定和对第三方控件的支持即将推出。
Windows ARM64
.NET应用程序现在可以在Windows ARM64上本机运行。 这遵循了我们在.NET Core 3.0中为Linux ARM64添加的支持。 使用.NET 5.0,您可以在Windows ARM64设备上开发Web和UI应用程序,并将应用程序交付给拥有Surface Pro X和类似设备的用户。 您已经可以通过x86仿真在Windows ARM64上运行.NET Core和.NET Framework应用程序。 它是可行的,但本机ARM64执行具有更好的性能。
您可以在今天的预览版4中下载并使用ARM64上的.NET 5.0 SDK。 当前,仅支持控制台和ASP.NET Core应用程序。 请参阅.NET 5.0 ARM64跟踪问题以跟踪进度。
master
分支添加了对Windows Forms的支持。 此更改可能会使它进入“预览5”,但可以肯定地进入“预览6”。 您可以从dotnet / installer下载master
分支版本。
当前,您需要下载和扩展ARM64的.zip
文件。 我们打算为最终的.NET 5版本添加ARM64 MSI。
我们一直与PowerShell团队紧密合作,以在Windows ARM64上验证并启用PowerShell 7.1。 该团队拥有Windows ARM64“实验性”构建已有一段时间,并打算在Windows ARM64发布时支持Windows ARM64上的PowerShell 7.1。 PowerShell 7.1建立在.NET 5.0上,应在大约同一时间发布。
下图演示了在Windows ARM64上运行的Conway生活游戏 VB和Windows Forms示例。
ARM64性能
一年多来,我们一直在大力投资以提高ARM64性能。 我们致力于使ARM64成为.NET的高性能平台。 平台的可移植性和一致性一直是.NET的引人注目的特征。 这包括在任何使用.NET的地方都提供出色的性能。 使用.NET Core 3.x,ARM64与x64具有同等的功能,但是缺少一些关键的性能和投资。 我们正在.NET 5.0中进行ARM64性能方面的第一笔重大投资。
我们正在进行几类改进:
调整ARM64的JIT优化( 示例 )
启用并利用ARM64硬件内部函数( 示例 )。
调整ARM64库中对性能至关重要的算法( 示例 )。
请参阅在.NET 5.0中提高ARM64性能以跟踪我们的进度。
硬件内在属性是我们在.NET Core 3.0中添加的低级性能功能 。 当时,我们增加了对x64指令和芯片的支持。 作为.NET 5.0的一部分,我们正在扩展该功能以支持ARM64。 仅创建内在函数并不能提高性能。 您需要在对性能有要求的代码中使用它们。 我们在.NET 5.0的.NET库中充分利用了ARM64内在函数 。 您也可以在自己的代码中执行此操作,尽管您需要熟悉CPU指令才能执行此操作。
我将以类比的方式解释硬件内部函数的工作方式。 在大多数情况下,开发人员都依赖于.NET中内置的类型和API,例如String.Split
或HttpClient
。 这些API通常通过P / Invoke功能利用本机操作系统API。 P / Invoke可以实现高性能的本机互操作,并且为此目的在BCL中广泛使用。 您可以自己使用此功能来调用本机API。 硬件内在函数相似,除了代替调用操作系统API之外,它们使您可以直接在代码中使用CPU指令。 它大致等效于.NET版本的C ++内部函数 。 最好将硬件固有特性视为CPU硬件加速功能。 它们提供了非常明显的好处,现在已经成为.NET库性能基础的关键部分,并且对您在我们的性能博客文章中了解到的许多好处负责。 与C ++相比,当将.NET内在函数AOT编译为“准备运行”文件时,内在函数不会损害运行时性能。
注意:Visual C ++编译器具有类似的内在功能 。 您可以直接将C ++与.NET硬件内在函数进行比较,就像您在System.Runtime.Intrinsics.X86.Avx2 , x64(amd64)内在函数列表和Intel Intrinsics指南中搜索_mm_i32gather_epi32
。 您将看到很多相似之处。
我们正在5.0中进行ARM64性能方面的第一笔重大投资,但将在以后的版本中继续这项工作。 我们直接与ARM Holdings的工程师合作,确定产品改进的优先级,并设计最能利用ARMv8 ISA的算法。 其中一些改进将为ARM32带来价值,但是,我们并未对ARM32进行独特的努力。
请与我们分享与ARM64有关的任何性能信息,无论是从3.1到5.0的显着改进,还是5.0更好的性能。
P95 +延迟
我们看到越来越多的大型面向Internet的站点和服务托管在.NET上。 尽管合理地关注每秒请求数(RPS)指标 ,但我们发现很少有大型网站所有者向我们询问或要求数百万RPS。 但是,我们听到了很多有关延迟的信息,特别是关于改善P95或P99延迟的信息 。 通常,根据实现特定的P95指标(而不是说P50)来选择为站点配置的机器或核心数量(以及最大的成本驱动因素)。 我们认为延迟是真正的“金钱指标”。
我们在StackOverflow的朋友在共享服务数据方面做得很好。 他们的一位工程师Nick Craver最近分享了他们看到的对延迟的改进 ,这是由于迁移到.NET Core所致:
问题的页面渲染中值时间从大约21毫秒(由于GC而有所增加)降至约15毫秒。
第95个百分位数从〜40ms下降至〜30ms(相同测量)。 第99位从〜60ms降至〜45ms。
考虑到我们还没有优化任何东西,所以不要太寒酸。 pic.twitter.com/MMHjI9wkuL
-Nick Craver(@Nick_Craver) 2020年3月31日
虽然您可以看到我们在延迟方面取得了良好的进展,但我们仍然不满意。 在过去(遥远的过去),我们分别利用多核和线程这样的进程化CPU功能来构建服务器GC和后台GC之类的功能,以改善延迟。 这些仍然很重要,但是,至少在与GC有关的情况下,我们需要发挥更大的创造力来显着改善向前的延迟。 我们已经沿着这些路线启动了多个项目。
固定对象一直是GC性能的长期挑战,特别是因为它们会加速(或导致)内存碎片。 我们为固定对象添加了新的GC堆 。 固定对象堆基于以下假设:进程中固定对象很少,但是它们的存在会带来不成比例的性能挑战。 将固定的对象(尤其是由.NET库作为实现细节创建的对象)移动到唯一的区域是有意义的,从而使世代GC堆几乎没有或没有固定的对象,从而具有更高的性能。
最近,我们一直在解决GC中长期存在的“难题”。 dotnet / runtime#2795将新方法应用于GC静态扫描,从而在确定GC堆对象的活动性时避免了锁争用。 dotnet / coreclr#25986使用新算法在垃圾回收的标记阶段平衡内核之间的GC工作,这应增加大堆垃圾回收的吞吐量,从而减少延迟。
容器
我们认为容器是最重要的云趋势,并且已经在这种模式上进行了大量投资。 我们正在.NET软件堆栈的多个级别上,以至少四种不同的方式对容器进行投资。
首先是我们对基本面的投资。 为这些投资申请信用有点奇怪,因为它们也使非集装箱式工作负载受益。 可能并不明显的是,我们收到的越来越多影响我们的基础投资的反馈来自部署容器化应用程序的开发人员。 这些投资会使集装箱产生偏差。
我们正在努力使.NET在容器中表现更好。 我们听说有报道说, 与去年下半年.NET Core 3.1的更改 (后来又恢复) 有关,性能不佳 。 现在,我们正在研究在高密度和其他配置中使用.NET的性能,以帮助告知我们我们期望的是范围相对较大的一组更改,这些更改将为容器带来下一次显着的性能改进。 应该注意的是, .NET Core 3.0是.NET和容器的一个非常大的版本 ,而3.1问题则是一个短暂的问题。
我们一直在寻找机会来改善我们发布的图像。 这包括减小图像尺寸 ,但还扩展了我们发布的图像集。 我们已决定根据在GitHub和其他来源上收到的反馈, 开始发布Windows Server Core映像 。 以下是示例Dockerfile ,将在我们开始发布这些映像时使用。 我们进行了其他更改,以减小Windows Server Core映像的大小 ,从而使它们更具吸引力。
最后,我们正在努力简化与容器编排器和类似环境的合作。 我们将增加对OpenTelemetry的支持,以便您可以从应用程序中捕获分布式跟踪和度量 。 我们还在工作于dotnet / tye回购中的一组新的实验工具,旨在提高微服务开发人员的生产力,无论是用于开发还是部署到Kubernetes环境。
改善分层编译性能
我们一直在努力改进多个版本的分层编译 。 我们仍然将其视为启动和稳态性能的关键性能特征。 在此版本中,我们对分层编译进行了两项重大改进。
分层编译的主要机制是调用计数。 一旦某个方法被调用了n次,运行时就会要求JIT以更高的质量重新编译该方法。 从我们最早的性能分析来看,我们知道呼叫计数机制太慢了(从长远的角度来看),但是没有找到解决该问题的直接方法。 作为.NET 5.0的一部分,我们改进了分层JIT编译所使用的调用计数机制 ,以平滑启动期间的性能。 在过去的发行版中,我们已经看到报告指出,在进程生存期的前10到15秒钟内,性能会发生不可预测的变化(主要是针对Web服务器)。 现在应该解决。 请对其进行测试,并告诉我们您看到了什么。
我们发现的另一个性能挑战是对带有循环的方法使用分层编译。 根本问题是,您可以使用带有循环迭代一百万次的冷方法(仅调用一次或几次; 这种病理情况的一个很好的例子是应用程序的Program.Main
方法。 结果,默认情况下,我们禁用了带循环方法的分层编译。 相反,我们使应用程序可以选择对具有循环的方法使用分层编译。 在某些情况下看到了个位数的高性能改进后,PowerShell是选择执行此操作的应用程序。
为了更好地解决循环问题,我们实现了栈上替换(OSR) 。 这类似于Java虚拟机具有的同名功能。 OSR允许在方法执行过程中重新编译当前正在运行的方法执行的代码,而那些方法是“堆栈上”活动的。 此功能目前处于实验状态,可以选择启用(在x64上)。
要使用OSR,必须启用多个功能。 PowerShell项目文件是一个很好的起点。 您会注意到分层编译和所有快速向导功能均已启用。 另外,您需要设置COMPlus_TC_OnStackReplacement=1
(它是一个环境变量)。
另外,您可以设置以下两个环境变量,假设所有其他设置均为默认值:
COMPlus_TC_QuickJitForLoops=1
COMPlus_TC_OnStackReplacement=1
我们不打算在.NET 5.0中默认启用OSR,并且尚未决定是否在生产中支持OSR。 请向我们提供您对该功能的任何反馈。 我们现在正在积极测试它,以后将分享更多的见解。
单文件应用
在某些情况下,人们希望使用.NET要求或至少希望使用单文件分发。 我们一直在构建在多个发行版中启用此方案所需的关键部分,并将在.NET 5.0中包括一个新的单个文件发布类型 。 我们希望此功能可以在多个版本中继续完善。
有两个方面使此功能的构建成本很高:
考虑到Linux和Windows上用于从本地资源中加载可执行内容的不同功能集和约束。
确保调试器为单文件应用程序提供类似多文件的体验。
为了进行范围界定,我们在Windows和Linux的X64(用于.NET 5.0)上支持此功能。 它将适用于ARM32 / 64应用程序,但是,我们未针对此版本的ARM体系结构主动验证单个文件应用程序。 单个文件将同时支持与运行时相关的和独立的发布类型 。
Windows和Linux之间的体验是相似的,但并不相同。 差异主要与独立的单文件应用程序有关,如单文件发布设计文档所述 :
单文件发布Linux:
dotnet publish -r linux-x64 /p:PublishSingleFile=true
发布的文件:
HelloWorld
,HelloWorld.pdb
单文件发布Windows:
dotnet publish -r win-x64 /p:PublishSingleFile=true
发布的文件:
HelloWorld.exe
,HelloWorld.pdb
,coreclr.dll
,clrjit.dll
,clrcompression.dll
,mscordaccore.dll
如您所见,在Windows上,单文件自包含应用程序除了该应用程序外还需要四个其他文件。 我们无法将这些运行时文件包含到单个文件应用程序中。 我们目前尚无在Windows上隐藏这些额外文件的技术计划,即使我们知道它是首选。
注意: .pdb
文件仅在调试mscordaccore.dll
需要,而mscordaccore.dll
是收集故障转储所必需的,包括Windows错误报告(又名“ Watson”) 。
改善从NewtonSoft.Json到System.Text.Json的迁移
我们将System.Text.Json添加为.NET Core 3.0版本的一部分。 与Newtonsoft.Json相比 ,它提供了显着的性能改进,后者已成为.NET的首选Json库。 在某些情况下,即使使用我们提供的迁移指南 ,也很难迁移到System.Text.Json。 我们一直在研究目标功能,这些功能使迁移更容易,同时又不放弃System.Text.Json的性能价值主张。
我们在.NET 5.0中添加了以下迁移功能:
添加对JSON保留引用的支持 - 启用
ReferenceLoopHandling
。添加
JsonConstructor
并支持使用参数化JsonConstructor
进行反序列化 —向JsonSerializer添加对不可变类和结构的支持。添加JsonIgnoreCondition和按属性忽略逻辑 –添加对空值处理的支持。
添加JsonIncludeAttribute和对非公共访问者的支持 -启用非公共获取方法的用法,类似于Newtonsoft.Json
JsonProperty
属性的功能。
同时,我们还在改善System.Text.Json的可用性:
添加新的System.Net.Http.Json项目/名称空间 – 为HttpClient添加新的扩展方法,该方法允许从JSON序列化到JSON 。
将复制构造函数添加到JsonSerializerOptions –使框架库可以管理
JsonSerializerOptions
实例,并为其设置特定的值,而类型随时间推移而版本化。
WinRT互操作
我们正在迁移到一个新模型,以作为.NET 5.0的一部分来支持WinRT API 。 这包括调用API(在任一方向上;CLR <==> WinRT),两个类型系统之间的数据封送处理以及旨在跨越边界被视为相同类型的类型的统一(即“投影类型”; IEnumerable<T>
和IIterable<T>
是示例)。
我们将依靠WinRT团队在Windows中提供的一组新的WinRT工具 ,这些工具将生成基于C#的WinRT互操作程序集。 我们目前正在与该团队紧密合作。 工具和由它们生成的程序集将在.NET 5.0中交付。
新系统有几个好处:
可以独立于.NET运行时进行开发和改进。
与为其他操作系统(例如iOS和Android)提供的互操作系统对称。
可以利用许多其他.NET功能(AOT,C#功能,IL链接)。
简化.NET运行时代码库。
作为.NET 5.0的一部分,我们将从.NET运行时(和任何其他相关组件)中删除现有的WinRT互操作系统。 这意味着将需要重新构建将WinRT与.NET Core 3.x结合使用的应用程序,并且这些应用程序不能按原样在.NET 5.0上运行。
开源项目改进
我们非常关心开源,包括使.NET社区能够在GitHub上高效工作,以及使.NET项目对大量开发人员可用。 我们一直在沿着这些思路开展各种举措。
dotnet / source-build支持使用单个命令从源代码构建整个.NET项目/产品。 红帽使用此项目来构建他们分发的.NET Core版本,我们在此上与他们紧密合作。 Fedora还使用源代码构建在其程序包存储库中启用.NET Core。 我们希望使任何开发人员,组织或公司都可以直接使用源代码构建,并且正在对该项目进行大量投资。 您可以直接按照.NET 5.0进行源构建 。
我们以太多的GitHub存储库开始了.NET Core项目。 在最高时,我们有超过100个回购。 这对于包括.NET团队在内的任何人来说都太过有意义了。 作为.NET 5.0项目的一部分,我们决定将存储库的数量减少到一个小型且易于管理的集合中。 我们宣布了在2019年8月合并.NET仓库的打算 ,然后在下一个10月提供了该计划的最终更新 。 作为该计划的一部分,我们将许多存储库合并在一起,现在几乎所有.NET存储库都位于dotnet org中 ,包括dotnet / aspnetcore 。 作为努力的一部分,我们保留了回购历史记录,这有一些有趣的副作用 。 我们将继续使用旧的存储库来维护2.1和3.1产品版本。 MSBuild和NuGet客户端存储库保留在其他组织中。
我们还致力于减少大多数存储库的构建时间 。 更快的构建时间使每个人的工作效率更高,并使您更快地查看PR的构建结果。 这是一项长期的工作,并且在以后的发行版中将重复一个主题。 您可以在.NET 5 Build Time Reduction Status处跟踪进度。
我们主要致力于产品的改进,但是最近我们将注意力转向为贡献者和其他参与者改进.NET开源项目。 我们最近要求提供有关改进项目的反馈以及参与.NET repos的经验 。 对我们来说重要的是,每个人都觉得自己对.NET项目存储库有发言权(就项目相关的话题),他们受到很好的对待,并且可以实现自己的目标。 这并不意味着我们接受所有提出的PR或建议。 与我们的方法有关,我们打算使用清晰的语言,对我们的参与保持友善态度,并鼓励做出贡献。 我们说对了吗? 您希望我们做些什么或做得更好? 请给我们您对我们回购贡献经验调查的反馈。
我们多次被要求澄清和开放.NET Core许可证。 每次将源和二进制资产转移到MIT许可证时,我们都这样做了。 最近,我们澄清了用于.NET Windows构建的许可证 。 对于大多数用户而言,这些更改无关紧要,但对于其他用户而言,它们确实重要,我们已尽力满足他们的需求。
预览4中的新改进
以下改进是Preview 4中的新增功能,之前的重点部分中未进行其他介绍。
C#9
.NET 5.0预览4包括C#9的第一个预览。C#9预览包括许多功能,包括记录的第一个预览,顶级语句的第一个预览,改进的模式匹配等等。 这是一些模式匹配改进的简要介绍:
using System; | |
public enum LifeStage | |
{ | |
Prenatal, | |
Infant, | |
Toddler, | |
EarlyChild, | |
MiddleChild, | |
Adolescent, | |
EarlyAdult, | |
MiddleAdult, | |
LateAdult | |
} | |
public class C | |
{ | |
// "is not" patterns | |
public static bool IsNotNull<T>(T item) => item is not null; | |
// Relational patterns | |
public static LifeStage LifeStageAtAge(int age) => | |
age switch | |
{ | |
< 0 => LifeStage.Prenatal, | |
< 2 => LifeStage.Infant, | |
< 4 => LifeStage.Toddler, | |
< 6 => LifeStage.EarlyChild, | |
< 12 => LifeStage.MiddleChild, | |
< 20 => LifeStage.Adolescent, | |
< 40 => LifeStage.EarlyAdult, | |
< 65 => LifeStage.MiddleAdult, | |
_ => LifeStage.LateAdult, | |
}; | |
} |
Sharplab.io上使用相同的代码。
敬请关注我们明天发布的所有细节的博客文章。
F#5
在今年早些时候发布的F#5预览版的基础上,对F#5的更新包括对使用默认接口方法(DIM)的支持以及一些重大的性能改进。 下面是F#对DIM的支持:
using System; |
public enum LifeStage |
{ |
Prenatal, |
Infant, |
Toddler, |
EarlyChild, |
MiddleChild, |
Adolescent, |
EarlyAdult, |
MiddleAdult, |
LateAdult |
} |
public class C |
{ |
// "is not" patterns |
public static bool IsNotNull<T>(T item) => item is not null; |
// Relational patterns |
public static LifeStage LifeStageAtAge(int age) => |
age switch |
{ |
< 0 => LifeStage.Prenatal, |
< 2 => LifeStage.Infant, |
< 4 => LifeStage.Toddler, |
< 6 => LifeStage.EarlyChild, |
< 12 => LifeStage.MiddleChild, |
< 20 => LifeStage.Adolescent, |
< 40 => LifeStage.EarlyAdult, |
< 65 => LifeStage.MiddleAdult, |
_ => LifeStage.LateAdult, |
}; |
} https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLQAdYwggdsgZgB8ABAJgEYBYAKFpIIAIJc4BbRgGQEtIBlGFADmEWgG9ajKYwAKSXLCgAbADSTpASVxgouGGprTGAFQD2AE3NKcBowFEoCJQE8AwgAtuS87ekBZbktrDy8fdSkAQXNTa2QAYxZ9cMYHJ2couCUkw39AqwgMrN8pTlgC80yYWgBfWnomckZXcWSAelbGACJuZEZcUxhOxkwYbDxkZIZGEgoANkZgUxjGDWQAOQG1zKUAHmMAPgAKY0ZubDYASkYAXn3T89Pe/pg+7YBuZLaOgCUIJVhuKYFEphlgcPhJg05lxeBABMIIDD+IIRBEYBERIduHpGAirrdkkYEYxkAB3M5xdyE6QSHJGemMHaMAAMNzuSLhKIgADo5CxFKpqQymWQ2SVYfCRNytDo9MUGdImQAWMUcyU8sxBGxC+lM+a3cXIhHc1IuELeeUKxmMCiig08I1SgJa81hOlW61kVn2iVc7lRGIoBJynVGZXeu4OznG03pCpFUOKxizACsYqj6u5zvyhWyHukAH1VYbo1LSthc5bpNUPjRajQgA== |
敬请关注明天详细介绍的博客文章。
C#源代码生成器更新
此版本还包括对C#Source Generators预览的更新。 除了修复一些错误外,它还支持将analyzerconfig(本质上是键值对列表)传递给Source Generator。 这使您的源生成器可以根据收到的输入来进行不同的工作。 例如,如果消费项目针对.NET Framework与.NET 5,则可能希望生成不同的源代码。使用analyzerconfig,您可以像消费项目的TFM这样传递信息,以完全满足这种情况。
在Windows上支持ICU
我们使用ICU库,该库为Linux和macOS上的应用程序提供Unicode和全球化支持。 我们现在在Windows上使用相同的库 。 此更改使全球化API的行为(例如特定于区域性的字符串比较)在Windows 10与其他操作系统之间保持一致。
支持cgroup v2(用于容器)
.NET现在已支持cgroup v2 ,我们预计它将在2020年及以后成为与容器相关的重要API。 Docker当前使用cgroup v1(.NET已经支持)。 相比之下,cgroup v2比cgroup v1更简单,更高效且更安全。 您可以从我们的2019年Docker更新中了解有关cgroup和Docker资源限制的更多信息。 Linux发行版和容器运行时正在增加对cgroup v2的支持 。 一旦变得更常见,.NET 5.0将在cgroup v2环境中正常工作。 感谢在Red Hat支持.NET的Omair Majid 。
减少容器图像的大小
我们一直在寻找使.NET容器映像更小,更易于使用的机会。 我们对Preview 4进行了一项更改,该更改可以显着减小您在多阶段构建方案中提取的聚合图像的大小(这是一种非常常见的模式)。 我们将SDK映像重新基于ASP.NET映像,而不是buildpack-deps 。
对于多阶段构建,此更改具有以下优势( Dockerfile中的示例用法):
Ubuntu 20.04 Focal的多阶段构建成本:
拉图像 | 之前 | 后 |
---|---|---|
sdk:5.0-focal | 268兆字节 | 232兆字节 |
aspnet:5.0-focal | 64兆字节 | 10 KB(仅清单) |
净下载节省量 :100 MB(-30%)
Debian 10 Buster的多阶段构建成本:
拉图像 | 之前 | 后 |
---|---|---|
sdk:5.0 | 280兆字节 | 218兆字节 |
aspnet:5.0 | 84兆字节 | 4 KB(仅清单) |
净下载节省量 :146 MB(-40%)
有关更多详细信息,请参见dotnet / dotnet-docker#1814 。
此更改有助于多阶段构建,其中目标的sdk
和aspnet
或runtime
映像是同一版本(我们希望这是常见的情况)。 进行此更改后, aspnet
pull(例如)将变为无操作,因为您将通过初始sdk
pull来拉伸aspnet
层。
如果您想了解更多背景信息,请继续阅读。 对于3.1及更低版本 ,SDK基于buildpack-deps映像。当我们开始生成容器映像时,我们注意到其他使用buildpack-deps作为其工具/ SDK映像基础的开发平台,因此我们遵循已建立的模式。我们特别依赖于该scm
层,该层包括源代码控制工具,并基于该curl
层,该层包括curl和类似的网络工具。这意味着您可以在SDK映像中使用所有这些工具。不幸的是,这种方法需要付出很大的代价。由于Docker仅允许单行继承(每个映像只能有一个父级),因此该sdk
映像需要携带自己的ASP.NET副本,并且Docker在sdk
映像中看不到实际上相同的ASP.NET字节,因为与中的相同aspnet
图片。这种情况需要存储和传输大量浪费的字节。另一方面,人们不想放弃使用所提供的工具。buildpack-deps
作为折衷方案,我们重新基于sdk
on aspnet
,增加了一些工具,同时保留了90%以上的尺寸节省。
该说明描述了我们对Ubuntu所做的工作。与Debian的故事更为复杂,并为赢得更大的胜利负责。总之,Debian的变体aspnet
和runtime
是基于Debian的变体,而是基于非纤细的Debian图像。这意味着对于使用Debian的多阶段构建,您需要两次拉Debian!到目前为止,甚至还没有共享发行层。-slim
buildpack-deps
我们对Alpine和Nano Server进行了类似的更改。Alpine或Nano Server 没有图像。但是,用于Alpine和Nano Server 的图像以前并未建立在ASP.NET图像之上。我们解决了。对于多阶段构建,您将看到Alpine和Nano Server以及5.0的巨大成功。buildpack-deps
sdk
我们很早就知道了这些问题,但是从来没有解决过这些问题。我们认为5.0版本是追逐这些规模胜利的好时机。请告诉我们是否有我们没想到的粗糙边缘。
.NET 5.0将切换到dotnet
容器存储库
作为将产品名称更改为“ .NET”的一部分,我们现在将.NET 5.0 Preview 4和更高版本的图像发布到回购系列中,而不是。请相应地更新您的语句和脚本。.NET Core 3.1和2.1将继续发布到.NET 。mcr.microsoft.com/dotnet
mcr.microsoft.com/dotnet/core
FROM
mcr.microsoft.com/dotnet/core
最后
.NET 5.0即将成为另一个大型基础版本,非常类似于.NET Core 1.0、2.0和3.0。它包括许多新的改进,应该使您的应用程序和开发过程变得更好,更容易。自从发布.NET Core 3.0以来,许多团队一直在研究.NET 5。几个月以来,我们一直期待着以最终形式发布所有这些改进,现在当您尝试它们时,将一直在等待您的反馈。
从您选择的产品投资中可以看出,我们专注于现代方案,并为您提供了直接且可预测的解决方案,这些解决方案可为您运行业务或组织所需的应用程序组合提供动力。对我们来说至关重要的是,您要向我们提供反馈,以帮助我们改进您在此处已阅读的功能,并希望您接下来能看到这些功能。就像您在文章的前面看到的那样,我们已经在计划.NET 6.0发行版了,因此为时过早的反馈给我们还为时过早。
请在https://aka.ms/dotnet5_feedback_blog上分享您对.NET的反馈。
出处:https://devblogs.microsoft.com/dotnet/announcing-net-5-preview-4-and-our-journey-to-one-net/
翻译:google翻译