.NET Framework 中的新增功能
注意
.NET Framework 单独提供服务,不依赖于 Windows 更新,并针对安全性和可靠性进行漏洞修复。 一般情况下,安全更新会按季度发布。 .NET Framework 将继续包含在 Windows 中,无需计划将其删除。 无需迁移 .NET Framework 应用,但对于新开发,请使用 .NET 8 或更高版本。
本文总结了以下 .NET Framework 版本中的主要新功能和改进:
- .NET Framework 4.8.1
- .NET Framework 4.8
- .NET Framework 4.7.2
- .NET Framework 4.7.1
- .NET Framework 4.7
- .NET Framework 4.6.2
- .NET Framework 4.6.1
- .NET 2015 和 .NET Framework 4.6
- .NET Framework 4.5.2
- .NET Framework 4.5.1
- .NET Framework 4.5
本文不提供有关每个新功能的完整信息,并且可能会更改。 有关 .NET Framework 的一般信息,请参阅 入门。 有关支持的平台,请参阅 系统要求。 有关下载链接和安装说明,请参阅 安装指南。
注意
.NET Framework 团队还使用 NuGet 在带外发布功能,以扩展平台支持并引入新功能,例如不可变集合和启用了 SIMD 的矢量类型。 有关详细信息,请参阅 其他类库和 API,.NET Framework 和带外版本。 请参阅用于 .NET Framework 的 完整 NuGet 包列表。
.NET Framework 4.8.1 简介
.NET Framework 4.8.1 基于早期版本的 .NET Framework 4.x,添加了许多新的修补程序和多项新功能,同时保持了非常稳定的产品。
下载并安装 .NET Framework 4.8.1
可以从以下位置下载 .NET Framework 4.8.1:
.NET Framework 4.8 可安装在 Windows 11、Windows 10 版本 21H2、Windows 10 版本 21H1、Windows 10 版本 20H2 以及从 Windows Server 2022 开始的相应服务器平台上。 可以使用 Web 安装程序或脱机安装程序安装 .NET Framework 4.8.1。 大多数用户的建议方法是使用 Web 安装程序。
通过安装 .NET Framework 4.8.1 开发人员包,可以在 Visual Studio 2022 17.3 或更高版本中将目标设为 .NET Framework 4.8.1。
.NET Framework 4.8.1 中的新增功能
.NET Framework 4.8.1 在以下方面引入了新功能:
改进了辅助功能,使应用程序可以为辅助技术的用户提供适当的体验,这是 .NET Framework 4.8.1 的主要重点。 有关 .NET Framework 4.8.1 中辅助功能改进的信息,请参阅 .NET Framework 中辅助功能的新增功能。
.NET Framework 4.8.1 为 .NET Framework 系列添加了对 Arm64 的本机支持。 因此,您对庞大 .NET Framework 应用和库生态系统的投资现在可以利用在 Arm64 上原生运行工作负载的好处,与在 Arm64 上模拟运行 x64 代码相比,性能更佳。
Microsoft 致力于提供所有人都能访问的产品和平台。 .NET Framework 4.8.1 提供两个 Windows UI 开发平台,这两个平台都为开发人员提供了创建可访问的应用程序所需的支持。 在过去几个版本中,Windows 窗体和 WPF 都添加了新功能,并修复了许多与辅助功能相关的可靠性问题。 可以通过访问 .NET Framework 中辅助功能的新增功能,详细了解每个版本中已修复或添加的内容的详细信息。
在此版本中,Windows 窗体和 WPF 都改进了工具提示的处理,使它们更易于访问。 在这两种情况下,工具提示现在都符合悬停或焦点指南中 WCAG2.1 内容中规定的指导方针。 工具提示的要求如下:
- 工具提示必须通过鼠标悬停或通过键盘导航到控件来显示。
- 工具提示应可消除。 也就是说,像 Esc 这样的简单键盘命令应消除工具提示。
- 工具提示应支持鼠标悬停。 用户应能够将鼠标光标悬停在工具提示上。 这使得像使用放大镜这样的场景能够为低视力用户读取工具提示。
- 工具提示应是永久性的。 工具提示在经过一定时间后不应自动消失。 相反,用户应通过将鼠标移动到另一个控件或使用键盘命令来关闭工具提示。
在 Windows 窗体中,此支持仅适用于 Windows 11 或更高版本的操作系统。 Windows 窗体是依赖于 Windows API 的轻量化托管封装,新的工具提示行为仅在 Windows 11 中得以实现。 WPF 在其可访问的工具提示中没有操作系统版本依赖项。
WPF 在 .NET Framework 4.8 中实现了 WCAG2.1 兼容工具提示的大部分要求。 在此版本中,WPF 通过使用 Esc 键、Ctrl 键(本身)或组合 Ctrl+Shift+F10来轻松消除当前窗口中的工具提示,从而改进了体验。 在此版本中,转义键的范围被缩小为仅适用于当前窗口。 以前,它适用于应用程序中所有打开的工具提示。
Windows 窗体是第一个为 .NET Framework 创建的 Windows 用户界面堆栈。 因此,它最初是为了利用旧版辅助功能技术而创建的,但不符合当前的辅助功能要求。 在此版本中,Windows 窗体修复了多个问题。 若要查看有关辅助功能更改的完整列表,请访问 .NET Framework 中辅助功能的新增功能。
.NET Framework 4.8.1 中 Windows 窗体改进的要点包括:
文本模式支持 – Windows 窗体增加了对 UIA 文本模式的支持。 此模式使辅助技术能够逐字遍历 TextBox 或类似的文本控件的内容。 它允许在控件内选择文本并更改,并在光标处插入新文本。 Windows Forms 添加了对 TextBox、DataGridView 单元格、ComboBox 控件等的支持。
解决对比度问题 - 在多个控件中,Windows 窗体已将所选矩形的对比度更改为更暗且更可见。
修复了多个 DataGridView 问题:
- 滚动条名称已更新为一致。
- 讲述人现在可以专注于空的 DataGridView 单元格。
- 开发人员能够设置自定义 DataGridView 单元格的本地化控件类型属性。
- DataGridViewLink 单元格的链接颜色已更新,以更好地与背景形成对比。
.NET Framework 4.8 简介
.NET Framework 4.8 基于早期版本的 .NET Framework 4.x,添加了许多新的修补程序和多项新功能,同时保持了非常稳定的产品。
下载并安装 .NET Framework 4.8
可以从以下位置下载 .NET Framework 4.8:
.NET Framework 4.8 可以安装在 Windows 10、Windows 8.1、Windows 7 SP1 和从 Windows Server 2008 R2 SP1 开始的相应服务器平台上。 可以使用 Web 安装程序或脱机安装程序安装 .NET Framework 4.8。 大多数用户的建议方法是使用 Web 安装程序。
可以在 Visual Studio 2012 或更高版本中以 .NET Framework 4.8 为目标,通过安装 .NET Framework 4.8 开发人员包。
.NET Framework 4.8 中的新增功能
.NET Framework 4.8 在以下方面引入了新功能:
通过改进无障碍功能,.NET Framework 4.8 仍然专注于为使用辅助技术的残障用户提供更佳的使用体验。 有关 .NET Framework 4.8 辅助功能改进的详细信息,请参阅 .NET Framework 中辅助功能方面的新变化。
基类
减少 FIPS 对加密的影响。 在早期版本的 .NET Framework 中,当系统加密库配置为“FIPS 模式”时,托管加密提供程序类(如 SHA256Managed)会抛出 CryptographicException。 由于加密提供程序类的托管版本(与系统加密库不同)未经过 FIPS(联邦信息处理标准)140-2 认证,因此会引发这些异常。 由于几个开发人员使其开发计算机处于 FIPS 模式,因此通常会在生产系统中引发异常。
默认情况下,在面向 .NET Framework 4.8 的应用程序中,以下托管加密类在此示例中不再引发 CryptographicException:
- MD5Cng
- MD5CryptoServiceProvider
- RC2CryptoServiceProvider
- RijndaelManaged
- RIPEMD160Managed
- SHA256Managed
相反,这些类会将加密操作重定向到系统加密库。 此更改有效地消除了开发人员环境和生产环境之间的潜在混淆差异,并使本机组件和托管组件在同一加密策略下运行。 依赖于这些异常的应用程序可以通过将 AppContext 开关 Switch.System.Security.Cryptography.UseLegacyFipsThrow
设置为 true
来还原以前的行为。 有关详细信息,请参阅托管加密类不会在 FIPS 模式下引发 CryptographyException。
使用更新版本的 ZLib
从 .NET Framework 4.5 开始,clrcompression.dll 程序集使用 ZLib(用于数据压缩的本机外部库),以便为 deflate 算法提供实现。 clrcompression.dll 的 .NET Framework 4.8 版本更新为使用 ZLib 版本 1.2.11,其中包括多项关键改进和修复。
Windows Communication Foundation (WCF)
ServiceHealthBehavior 简介
运行状况终结点由业务流程工具广泛使用以基于其运行状况状态来管理服务。 监视工具还可以使用健康检查来跟踪和提供有关服务的可用性和性能的通知。
ServiceHealthBehavior 是一个 WCF 服务行为,该行为可扩展 IServiceBehavior。 添加到 ServiceDescription.Behaviors 集合中时,服务行为将执行以下操作:
返回带有 HTTP 响应代码的服务健康状态。 可以在查询字符串中指定 HTTP/GET 运行状况探测请求的 HTTP 状态代码。
发布有关服务运行状况的信息。 可以使用 HTTP/GET 请求和
?health
查询字符串来显示特定于服务的详细信息,包括服务状态、限制计数和容量。 对行为不正常的 WCF 服务进行故障排除时,可以轻松访问此类信息则很重要。
有两种方式公开健康端点并发布 WCF 服务健康信息:
通过代码。 例如:
ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://contoso:81/Service1")); ServiceHealthBehavior healthBehavior = host.Description.Behaviors.Find<ServiceHealthBehavior>(); healthBehavior ??= new ServiceHealthBehavior(); host.Description.Behaviors.Add(healthBehavior);
Dim host As New ServiceHost(GetType(Service1), New Uri("http://contoso:81/Service1")) Dim healthBehavior As ServiceHealthBehavior = host.Description.Behaviors.Find(Of ServiceHealthBehavior)() If healthBehavior Is Nothing Then healthBehavior = New ServiceHealthBehavior() End If host.Description.Behaviors.Add(healthBehavior)
通过使用配置文件。 例如:
<behaviors> <serviceBehaviors> <behavior name="DefaultBehavior"> <serviceHealth httpsGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors>
可以使用查询参数(例如 OnServiceFailure
、OnDispatcherFailure
、OnListenerFailure
、OnThrottlePercentExceeded
)查询服务的运行状况,并为每个查询参数指定 HTTP 响应代码。 如果查询参数省略 HTTP 响应代码,则默认使用 503 HTTP 响应代码。 例如:
OnServiceFailure:
https://contoso:81/Service1?health&OnServiceFailure=450
当 ServiceHost.State 大于 CommunicationState.Opened 时,将返回 450 HTTP 响应状态代码。
查询参数和示例:
OnDispatcherFailure:
https://contoso:81/Service1?health&OnDispatcherFailure=455
当任何通道调度程序的状态大于 CommunicationState.Opened时,将返回 455 HTTP 响应状态代码。
OnListenerFailure:
https://contoso:81/Service1?health&OnListenerFailure=465
当任何通道侦听器的状态大于 CommunicationState.Opened时,将返回 465 HTTP 响应状态代码。
OnThrottlePercentExceeded:
https://contoso:81/Service1?health&OnThrottlePercentExceeded= 70:350,95:500
指定触发响应的百分比 {1 – 100} 及其 HTTP 响应代码 {200 – 599}。 在此示例中:
如果百分比大于 95,则返回 500 HTTP 响应代码。
如果百分比介于 70 和 95 之间,则返回 350。
否则将返回 200。
可以通过指定查询字符串(如 https://contoso:81/Service1?health
),在 HTML 中显示服务运行状况状态;也可以通过指定查询字符串(如 https://contoso:81/Service1?health&Xml
)在 XML 中显示。 查询字符串(如 https://contoso:81/Service1?health&NoContent
)返回空的 HTML 页。
Windows Presentation Foundation (WPF)
高 DPI 增强功能
在 .NET Framework 4.8 中,WPF 添加了对 Per-Monitor V2 DPI 感知和 Mixed-Mode DPI 缩放的支持。 有关高 DPI 开发的其他信息,请参阅 Windows 上的
.NET framework 4.8 改进了对支持混合模式 DPI 缩放的平台上的高 DPI WPF 应用程序中的寄宿 HWND 和 Windows 窗体互操作的支持(从 Windows 10 2018 年 4 月更新开始)。 通过调用 SetThreadDpiHostingBehavior 和 SetThreadDpiAwarenessContext 将寄宿 HWND 或 Windows 窗体控件创建为混合模式 DPI 缩放窗口时,它们可以托管在按监视器 V2 WPF 应用程序中,并且相应地调整大小和缩放。 此类托管内容不会以原生 DPI 呈现,相反,操作系统会将托管内容缩放为适当的大小。 对按监视器 v2 DPI 感知模式的支持还允许 WPF 控件托管(即,设置为父级)在高 DPI 应用程序的本机窗口中。
若要启用对混合模式高 DPI 缩放的支持,可以设置以下 AppContext 切换应用程序配置文件:
<runtime>
<AppContextSwitchOverrides value = "Switch.System.Windows.DoNotScaleForDpiChanges=false; Switch.System.Windows.DoNotUsePresentationDpiCapabilityTier2OrGreater=false"/>
</runtime>
公共语言运行时
.NET Framework 4.8 中的运行时包括以下更改和改进:
对 JIT 编译器的改进。 .NET Framework 4.8 中的实时 (JIT) 编译器基于 .NET Core 2.1 中的 JIT 编译器。 .NET Framework 4.8 JIT 编译器中包含了许多优化和对 .NET Core 2.1 JIT 编译器所做的所有 bug 修复。
NGEN 改进。 运行时改进了本机映像生成器 (NGEN) 映像的内存管理,以便从 NGEN 映像映射的数据不驻留在内存中。 这将缩减可受到攻击的外围应用,攻击方法为试图通过修改将执行的内存来执行任意代码。
所有程序集的反恶意软件扫描。 在早期版本的 .NET Framework 中,运行时使用 Windows Defender 或第三方反恶意软件扫描从磁盘加载的所有程序集。 但是,从其他源(例如通过 Assembly.Load(Byte[]) 方法)加载的程序集不会被扫描,并且可能包含未检测到的恶意软件。 从 Windows 10 上运行的 .NET Framework 4.8 开始,运行时通过实现反恶意软件扫描界面 (AMSI) 的反恶意软件解决方案来触发扫描。
.NET Framework 4.7.2 中的新增功能
.NET Framework 4.7.2 包括以下方面的新功能:
.NET Framework 4.7.2 的持续关注是改进辅助功能的可访问性,这样应用程序就可以为辅助技术的用户提供适当的体验。 有关 .NET Framework 4.7.2 中的辅助功能改进的信息,请参阅 .NET Framework 中辅助功能的新特点。
基类
.NET Framework 4.7.2 具有大量加密增强功能、对 ZIP 存档的更好的解压缩支持和其他收集 API。
RSA.Create 和 DSA.Create 的新重载
DSA.Create(DSAParameters) 和 RSA.Create(RSAParameters) 方法允许在实例化新的 DSA 或 RSA 密钥时提供关键参数。 它们允许你替换如下所示的代码:
// Before .NET Framework 4.7.2
using (RSA rsa = RSA.Create())
{
rsa.ImportParameters(rsaParameters);
// Other code to execute using the RSA instance.
}
' Before .NET Framework 4.7.2
Using rsa = RSA.Create()
rsa.ImportParameters(rsaParameters)
' Other code to execute using the rsa instance.
End Using
采用类似如下所示的代码:
// Starting with .NET Framework 4.7.2
using (RSA rsa = RSA.Create(rsaParameters))
{
// Other code to execute using the rsa instance.
}
' Starting with .NET Framework 4.7.2
Using rsa = RSA.Create(rsaParameters)
' Other code to execute using the rsa instance.
End Using
使用 DSA.Create(Int32) 和 RSA.Create(Int32) 方法可以生成具有特定密钥大小的新 DSA 或 RSA 键。 例如:
using (DSA dsa = DSA.Create(2048))
{
// Other code to execute using the dsa instance.
}
Using dsa = DSA.Create(2048)
' Other code to execute using the dsa instance.
End Using
Rfc2898DeriveBytes 构造函数接受哈希算法名称
Rfc2898DeriveBytes 类有三个新构造函数,其中包含一个 HashAlgorithmName 参数,用于标识派生密钥时要使用的 HMAC 算法。 开发人员应使用基于 SHA-2 的 HMAC(如 SHA-256),而不是使用 SHA-1,如以下示例所示:
private static byte[] DeriveKey(string password, out int iterations, out byte[] salt,
out HashAlgorithmName algorithm)
{
iterations = 100000;
algorithm = HashAlgorithmName.SHA256;
const int SaltSize = 32;
const int DerivedValueSize = 32;
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, SaltSize,
iterations, algorithm))
{
salt = pbkdf2.Salt;
return pbkdf2.GetBytes(DerivedValueSize);
}
}
Private Shared Function DeriveKey(password As String, ByRef iterations As Integer,
ByRef salt AS Byte(), ByRef algorithm As HashAlgorithmName) As Byte()
iterations = 100000
algorithm = HashAlgorithmName.SHA256
Const SaltSize As Integer = 32
Const DerivedValueSize As Integer = 32
Using pbkdf2 = New Rfc2898DeriveBytes(password, SaltSize, iterations, algorithm)
salt = pbkdf2.Salt
Return pbkdf2.GetBytes(DerivedValueSize)
End Using
End Function
对临时密钥的支持
PFX 导入可以选择直接从内存中加载私钥,从而绕过硬盘驱动器。 如果在 X509Certificate2 构造函数或 X509Certificate2.Import 方法的其中一个重载中指定了新的 X509KeyStorageFlags.EphemeralKeySet 标记,则私钥将加载为临时密钥。 这可以防止密钥在磁盘上可见。 然而:
由于密钥不会保存到磁盘,因此使用此标志加载的证书不适合添加到 X509Store。
以这种方式加载的密钥几乎总是通过 Windows CNG 加载。 因此,调用方必须通过调用扩展方法(如 证书)来访问私钥。GetRSAPrivateKey()。 X509Certificate2.PrivateKey 属性不起作用。
由于旧 X509Certificate2.PrivateKey 属性不适用于证书,因此开发人员应在切换到临时密钥之前执行严格的测试。
以编程方式创建 PKCS#10 证书签名请求和 X.509 公钥证书
从 .NET Framework 4.7.2 开始,工作负载可以生成证书签名请求(CSR),这允许将证书请求生成暂存到现有工具中。 这在测试方案中通常很有用。
有关详细信息和代码示例,请参阅 .NET 博客中的“以编程方式创建 PKCS#10 证书签名请求和 X.509 公钥证书”。
新的 SignerInfo 成员
从 .NET Framework 4.7.2 开始,SignerInfo 类公开有关签名的详细信息。 可以检索 System.Security.Cryptography.Pkcs.SignerInfo.SignatureAlgorithm 属性的值,以确定签名者使用的签名算法。 可以调用 SignerInfo.GetSignature 以获取此签名者的加密签名的副本。
在 CryptoStream 释放后保持包装流打开
从 .NET Framework 4.7.2 开始,CryptoStream 类有了一个额外的构造函数可允许 Dispose 不关闭包装流。 若要在处置 CryptoStream 实例后使包装流保持打开状态,请调用新的 CryptoStream 构造函数,方法如下:
var cStream = new CryptoStream(stream, transform, mode, leaveOpen: true);
Dim cStream = New CryptoStream(stream, transform, mode, leaveOpen:=true)
DeflateStream 中的解压缩更改
从 .NET Framework 4.7.2 开始,DeflateStream 类中的解压缩操作的实现默认更改为使用本机 Windows API。 通常,这会导致大幅提高性能。
对于面向 .NET Framework 4.7.2 的应用程序,默认启用对使用 Windows API 进行解压缩的支持。 对于面向旧版 .NET Framework 但在 .NET Framework 4.7.2 下运行的应用程序,可以将以下 AppContext 开关添加到应用程序配置文件,从而选择启用此行为:
<AppContextSwitchOverrides value="Switch.System.IO.Compression.DoNotUseNativeZipLibraryForDecompression=false" />
额外的集合 API
.NET Framework 4.7.2 向 SortedSet<T> 和 HashSet<T> 类型添加了许多新 API。 其中包括:
TryGetValue
方法,该方法将其他集合类型中使用的 try 模式扩展到这两种类型。 方法包括:Enumerable.To*
扩展方法,将集合转换为 HashSet<T>:新的 HashSet<T> 构造函数,让你设置集合容量,可以在提前知道 HashSet<T> 大小的情况下提升性能:
ConcurrentDictionary<TKey,TValue> 类包括 AddOrUpdate 和 GetOrAdd 方法的新重载,用于从字典中检索值,如果未找到该值则添加,并用于在字典中添加一个值或如果该值已存在则更新它。
public TValue AddOrUpdate<TArg>(TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument)
public TValue GetOrAdd<TArg>(TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument)
Public AddOrUpdate(Of TArg)(key As TKey, addValueFactory As Func(Of TKey, TArg, TValue), updateValueFactory As Func(Of TKey, TValue, TArg, TValue), factoryArgument As TArg) As TValue
Public GetOrAdd(Of TArg)(key As TKey, valueFactory As Func(Of TKey, TArg, TValue), factoryArgument As TArg) As TValue
ASP.NET
Web 窗体中的依赖项注入支持
依赖关系注入(DI) 分离对象及其依赖项,以便不再需要更改对象的代码,因为依赖项已更改。 开发面向 .NET Framework 4.7.2 的 ASP.NET 应用程序时,可以:
同站点 cookie 支持
SameSite 阻止浏览器在跨站请求时发送 Cookie。 .NET Framework 4.7.2 添加一个 HttpCookie.SameSite 属性,其值为 System.Web.SameSiteMode 枚举成员。 如果其值 SameSiteMode.Strict 或 SameSiteMode.Lax,ASP.NET 将 SameSite
属性添加到 set-cookie 标头。 SameSite 支持适用于 HttpCookie 对象以及 FormsAuthentication 和 System.Web.SessionState cookie。
可以为 HttpCookie 对象设置 SameSite,如下所示:
var c = new HttpCookie("secureCookie", "same origin");
c.SameSite = SameSiteMode.Lax;
Dim c As New HttpCookie("secureCookie", "same origin")
c.SameSite = SameSiteMode.Lax
还可以通过修改 web.config 文件在应用程序级别配置 SameSite Cookie:
<system.web>
<httpCookies sameSite="Strict" />
</system.web>
通过修改 Web 配置文件,可以为 FormsAuthentication 和 System.Web.SessionState cookie 添加 SameSite:
<system.web>
<authentication mode="Forms">
<forms cookieSameSite="Lax">
<!-- ... -->
</forms>
</authentication>
<sessionState cookieSameSite="Lax"></sessionState>
</system.web>
联网
HttpClientHandler 属性的实现
.NET Framework 4.7.1 向 System.Net.Http.HttpClientHandler 类添加了八个属性。 不过其中有两个会引发 PlatformNotSupportedException。 .NET Framework 4.7.2 现在提供这些属性的实现。 这些属性包括:
SQLClient
支持 Azure Active Directory 通用身份验证和多重身份验证
越来越多的合规性和安全性要求要求许多客户使用多重身份验证(MFA)。 此外,当前最佳做法不建议在连接字符串中直接包括用户密码。 为了支持这些更改,.NET Framework 4.7.2 通过为现有“身份验证”关键字添加新值“Active Directory Interactive”来扩展 SQLClient 连接字符串,以支持 MFA,Azure AD 身份验证。 新的交互式方法支持本地和联合 Azure AD 用户以及 Azure AD 来宾用户。 使用此方法时,SQL 数据库支持 Azure AD 施加的 MFA 身份验证。 此外,身份验证过程会请求用户密码,以遵守安全最佳做法。
在早期版本的 .NET Framework 中,SQL 连接仅支持 SqlAuthenticationMethod.ActiveDirectoryPassword 和 SqlAuthenticationMethod.ActiveDirectoryIntegrated 选项。 这两者都是非交互式 ADAL 协议的一部分,不支持 MFA。 使用新的 SqlAuthenticationMethod.ActiveDirectoryInteractive 选项,SQL 连接支持 MFA 以及现有的身份验证方法(密码和集成身份验证),使用户能够以交互方式输入用户密码,而无需在连接字符串中保留密码。
有关详细信息和示例,请参阅 .NET 博客中的“SQL - Azure AD 通用和多重身份验证支持”。
Always Encrypted 版本 2 的支持
NET Framework 4.7.2 添加了对基于 enclave 的 Always Encrypted 的支持。 Always Encrypted 的原始版本是客户端加密技术,其中加密密钥永远不会离开客户端。 在基于飞地的 Always Encrypted 中,客户端可以选择性地将加密密钥发送到一个安全飞地,这是一个可以被视为 SQL Server 一部分的安全计算实体,但 SQL Server 代码无法篡改它。 为了支持基于 enclave 的 Always Encrypted,.NET Framework 4.7.2 将以下类型和成员添加到 System.Data.SqlClient 命名空间:
SqlConnectionStringBuilder.EnclaveAttestationUrl,,为基于 enclave 的 Always Encrypted 指定 URI。
SqlColumnEncryptionEnclaveProvider,一个抽象类,所有 enclave 提供程序都自它派生。
SqlEnclaveSession,封装给定 enclave 会话的状态。
SqlEnclaveAttestationParameters,提供证明参数,SQL Server 使用这些参数以获取执行特定证明协议所需的信息。
然后,应用程序配置文件指定抽象 System.Data.SqlClient.SqlColumnEncryptionEnclaveProvider 类的具体实现,该类提供 enclave 提供程序的功能。 例如:
<configuration>
<configSections>
<section name="SqlColumnEncryptionEnclaveProviders" type="System.Data.SqlClient.SqlColumnEncryptionEnclaveProviderConfigurationSection,System.Data,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"/>
</configSections>
<SqlColumnEncryptionEnclaveProviders>
<providers>
<add name="Azure" type="Microsoft.SqlServer.Management.AlwaysEncrypted.AzureEnclaveProvider,MyApp"/>
<add name="HGS" type="Microsoft.SqlServer.Management.AlwaysEncrypted.HGSEnclaveProvider,MyApp" />
</providers>
</SqlColumnEncryptionEnclaveProviders >
</configuration>
基于 enclave 的 Always Encrypted 的基本流是:
用户创建与 SQL Server(支持基于 enclave 的 Always Encrypted)的 AlwaysEncrypted 连接。 驱动程序联系认证服务以确保它连接到正确的 enclave。
enclave 验证成功后,驱动程序将建立与托管在 SQL Server 上的安全 enclave 之间的安全信道。
驱动程序在 SQL 连接期间与安全 enclave 共享客户端授权的加密密钥。
Windows Presentation Foundation
按源查找 ResourceDictionaries
从 .NET Framework 4.7.2 开始,诊断助手可以找到从给定源 URI 创建的 ResourceDictionaries。 (此功能供诊断助理使用,而不是生产应用程序使用。诊断助手(如 Visual Studio 的“编辑并继续”功能)允许用户编辑 ResourceDictionary,目的是将更改应用到正在运行的应用程序。 要实现这一点,其中一个步骤是从被编辑的字典中找到正在运行的应用程序创建的所有 ResourceDictionary。 例如,应用程序可以声明某个从给定源 URI 复制内容的 ResourceDictionary:
<ResourceDictionary Source="MyRD.xaml" />
编辑 MyRD.xaml 中的原始标记的诊断助手可以使用新功能来查找字典。 此功能由新的静态方法实现,ResourceDictionaryDiagnostics.GetResourceDictionariesForSource。 诊断助手使用标识原始标记的绝对 URI 调用新方法,如以下代码所示:
IEnumerable<ResourceDictionary> dictionaries = ResourceDictionaryDiagnostics.GetResourceDictionariesForSource(new Uri("pack://application:,,,/MyApp;component/MyRD.xaml"));
Dim dictionaries As IEnumerable(Of ResourceDictionary) = ResourceDictionaryDiagnostics.GetResourceDictionariesForSource(New Uri("pack://application:,,,/MyApp;component/MyRD.xaml"))
除非启用 VisualDiagnostics 并且设置了 ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO
环境变量,否则该方法将返回空枚举。
查找 ResourceDictionary 所有者
从 .NET Framework 4.7.2 开始,诊断助手可以找到给定 ResourceDictionary 的所有者。 (此功能供诊断助理使用,而不是由生产应用程序使用。每当对 ResourceDictionary进行更改时,WPF 都会自动查找所有 DynamicResource 可能受更改影响的引用。
诊断助手(例如 Visual Studio 的“编辑并继续”)可能想对此进行扩展以处理 StaticResource 引用。 此过程的第一步是查找字典的所有者;也就是说,查找其 Resources
属性引用字典的所有对象(直接或间接通过 ResourceDictionary.MergedDictionaries 属性)。 在 System.Windows.Diagnostics.ResourceDictionaryDiagnostics 类上实现了三个新的静态方法,分别对应于拥有 Resources
属性的基类型,来支持此步骤:
除非启用 VisualDiagnostics 并且设置了 ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO
环境变量,否则这些方法将返回空枚举。
查找 StaticResource 引用
诊断助手现在可以在解析 StaticResource 引用时接收通知。 (此功能用于诊断助手,而不是生产应用程序使用。)诊断助手(例如 Visual Studio 的“编辑并继续”工具)可能需要在 ResourceDictionary 的值发生变化时,更新所有资源的用途。 WPF 会自动为 DynamicResource 引用执行此操作,但有意不会对 StaticResource 引用执行此操作。 从 .NET Framework 4.7.2 开始,诊断助手可以使用这些通知来查找静态资源的使用。
通知由新的 ResourceDictionaryDiagnostics.StaticResourceResolved 事件实现:
public static event EventHandler<StaticResourceResolvedEventArgs> StaticResourceResolved;
Public Shared Event StaticResourceResolved As EventHandler(Of StaticResourceResolvedEventArgs)
每当运行时解析 静态资源 引用时,将引发此事件。 StaticResourceResolvedEventArgs 参数描述解析,并指示托管 StaticResource 引用的对象和属性及用于解析的 ResourceDictionary 和密钥:
public class StaticResourceResolvedEventArgs : EventArgs
{
public Object TargetObject { get; }
public Object TargetProperty { get; }
public ResourceDictionary ResourceDictionary { get; }
public object ResourceKey { get; }
}
Public Class StaticResourceResolvedEventArgs : Inherits EventArgs
Public ReadOnly Property TargetObject As Object
Public ReadOnly Property TargetProperty As Object
Public ReadOnly Property ResourceDictionary As ResourceDictionary
Public ReadOnly Property ResourceKey As Object
End Class
除非启用 VisualDiagnostics 并设置了 ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO
环境变量,否则不会引发该事件(且忽略它的 add
访问器)。
ClickOnce
Windows 窗体的 HDPI 感知应用程序、Windows Presentation Foundation (WPF) 以及 Visual Studio Tools for Office (VSTO) 都可以通过使用 ClickOnce 进行部署。 如果在应用程序清单中找到以下条目,则 .NET Framework 4.7.2 下的部署将成功:
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
对于 Windows 窗体应用程序,不需要像以前那样在应用程序配置文件(而非应用程序清单)中设置 DPI 感知就可以成功完成 ClickOnce 部署。
.NET Framework 4.7.1 中的新增功能
.NET Framework 4.7.1 包括以下方面的新功能:
此外,.NET Framework 4.7.1 中的一个主要重点是改进辅助功能,这使应用程序可以为辅助技术的用户提供适当的体验。 有关 .NET Framework 4.7.1 中辅助功能的改进信息,请参阅 .NET Framework中辅助功能中的新增功能。
基类
支持 .NET Standard 2.0
.NET Standard 定义了一组 API,这些 API 必须可用于支持该版本的标准的每个 .NET 实现。 .NET Framework 4.7.1 完全支持 .NET Standard 2.0,并添加 大约 200 个 API,这些 API 在 .NET Standard 2.0 中定义,并且 .NET Framework 4.6.1、4.6.2 和 4.7 中缺少这些 API。 (请注意,仅当目标系统上还部署了其他 .NET Standard 支持文件时,这些版本的 .NET Framework 才支持 .NET Standard 2.0。有关详细信息,请参阅 .NET Framework 4.7.1 运行时和编译器功能 博客文章中的“BCL - .NET Standard 2.0 支持”。
对配置生成器的支持
配置生成器允许开发人员在运行时动态注入和生成应用程序的配置设置。 自定义配置生成器可用于修改配置节中的现有数据,或完全从头开始生成配置节。 如果没有配置生成器,.config 文件是静态的,并且将在应用程序启动前一段时间定义其设置。
若要创建自定义配置生成器,请从抽象的 ConfigurationBuilder 类派生生成器并且替代其 ConfigurationBuilder.ProcessConfigurationSection 和 ConfigurationBuilder.ProcessRawXml。 还可以在 .config 文件中定义生成器。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET 和配置功能 博客文章中的“配置生成器”部分。
运行时功能检测
System.Runtime.CompilerServices.RuntimeFeature 类提供了一种机制,用于确定在编译时还是运行时给定的 .NET 实现上是否支持预定义功能。 在编译时,编译器可以检查指定的字段是否存在以确定是否支持该功能;如果是这样,它可以发出利用该功能的代码。 在运行时,应用程序可以在运行时发出代码之前调用 RuntimeFeature.IsSupported 方法。 有关详细信息,请参阅 Add helper method to describe features supported by the runtime(添加 helper 方法以描述运行时支持的功能)。
值元组类型可序列化
从 .NET Framework 4.7.1 开始,System.ValueTuple 及其关联的泛型类型标记为 可序列化,这允许二进制序列化。 这样,可以更轻松地将元组类型(如 Tuple<T1,T2,T3> 和 Tuple<T1,T2,T3,T4>)迁移到值元组类型。 有关详细信息,请参阅 .NET Framework 4.7.1 运行时和编译器功能 博客文章中的“Compiler -- ValueTuple 是可序列化的”。
支持只读引用
.NET Framework 4.7.1 添加了 System.Runtime.CompilerServices.IsReadOnlyAttribute。 语言编译器使用此属性来标记具有只读 ref 返回类型或参数的成员。 有关详细信息,请参阅 .NET Framework 4.7.1 运行时和编译器功能 博客文章中的“编译器——对只读引用的支持”。 有关 ref 返回值的信息,请参阅 ref 返回值和 ref 局部变量(C# 指南)和 ref 返回值 (Visual Basic)。
公共语言运行时 (CLR)
垃圾回收性能改进
.NET Framework 4.7.1 中的垃圾回收 (GC) 的更改提升了整体性能,尤其是大型对象堆 (LOH) 分配的性能。 在 .NET Framework 4.7.1 中,小型对象堆 (SOH) 分配和 LOH 分配使用不同的锁,当后台 GC 整理 SOH 时即发生 LOH 分配。 这样,进行大量 LOH 分配的应用程序发生分配锁争用的情况将减少,从而提高性能。 有关详细信息,请参阅 .NET Framework 4.7.1 运行时和编译器功能 博客文章中的“运行时 - GC 性能改进”部分。
联网
Message.HashAlgorithm 的 SHA-2 支持
在 .NET Framework 4.7 及更早版本中,Message.HashAlgorithm 属性仅支持 HashAlgorithm.Md5 和 HashAlgorithm.Sha 的值。 从 .NET Framework 4.7.1 开始,还支持 HashAlgorithm.Sha256、HashAlgorithm.Sha384和 HashAlgorithm.Sha512。 此值是否实际使用取决于 MSMQ,因为 Message 实例本身不会进行哈希处理,而只是将值传递给 MSMQ。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET 和配置功能 博客文章中的“Message.HashAlgorithm 的 SHA-2 支持”部分。
ASP.NET
ASP.NET 应用程序中的执行步骤
ASP.NET 处理包含 23 个事件的预定义管道中的请求。 ASP.NET 将每个事件处理程序作为执行步骤执行。 在 .NET Framework 4.7 及之前的 ASP.NET 版本中,由于本机线程和托管线程之间的切换,ASP.NET 无法传递执行上下文。 ASP.NET 有选择性地仅传送 HttpContext。 从 .NET Framework 4.7.1 开始,HttpApplication.OnExecuteRequestStep(Action<HttpContextBase,Action>) 方法还允许模块还原环境数据。 此功能针对与跟踪、分析、诊断或事务(例如应用程序的执行流)相关的库。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET 和配置功能 博客文章中的“ASP.NET 执行步骤功能”。
ASP.NET HttpCookie 分析
.NET Framework 4.7.1 包括一个新方法,HttpCookie.TryParse,该方法提供了一种标准化方法,用于从字符串创建 HttpCookie 对象,并准确分配过期日期和路径等 Cookie 值。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET and Configuration Features(.NET Framework 4.7.1 ASP.NET 和配置功能)博客文章中的“ASP.NET HttpCookie parsing”(ASP.NET HttpCookie 分析)一节。
ASP.NET 表单身份验证凭据的 SHA-2 哈希选项
在 .NET Framework 4.7 及更早版本中,ASP.NET 允许开发人员使用 MD5 或 SHA1 在配置文件中使用哈希密码存储用户凭据。 从 .NET Framework 4.7.1 开始,ASP.NET 还支持新的安全 SHA-2 哈希选项,例如 SHA256、SHA384 和 SHA512。 SHA1 保留默认值,可以在 Web 配置文件中定义非默认哈希算法。
重要
Microsoft建议使用可用的最安全的身份验证流。 如果要连接到 Azure SQL,建议使用 Azure 资源的托管标识这种身份验证方法。
.NET Framework 4.7 中的新增功能
.NET Framework 4.7 包括以下方面的新功能:
- 基类
- 网络
- ASP.NET
- Windows Communication Foundation (WCF)
- Windows 窗体
- Windows Presentation Foundation (WPF)
有关添加到 .NET Framework 4.7 的新 API 的列表,请参阅 GitHub 上的 .NET Framework 4.7 API 更改。 有关 .NET Framework 4.7 中的功能改进和 bug 修复的列表,请参阅 GitHub 上 .NET Framework 4.7 更改列表。 有关详细信息,请参阅 .NET 博客中的 宣布 .NET Framework 4.7。
基类
.NET Framework 4.7 通过 DataContractJsonSerializer改进序列化:
椭圆曲线加密(ECC)增强功能 *
在 .NET Framework 4.7 中,ImportParameters(ECParameters)
方法已添加到 ECDsa 和 ECDiffieHellman 类,以允许对象表示已建立的密钥。 还添加了 ExportParameters(Boolean)
方法,用于使用显式曲线参数导出密钥。
.NET Framework 4.7 还添加了对其他曲线(包括 Brainpool 曲线套件)的支持,并添加了预定义的定义,以便通过新的 Create 和 Create 工厂方法轻松创建。
可以在 GitHub 上查看 .NET Framework 4.7 加密改进
DataContractJsonSerializer 对控制字符提供了更好的支持
在 .NET Framework 4.7 中,DataContractJsonSerializer 类根据 ECMAScript 6 标准序列化控制字符。 对于面向 .NET Framework 4.7 的应用程序,此行为默认启用,对于在 .NET Framework 4.7 下运行但面向早期版本的 .NET Framework 的应用程序,此行为是一项选择加入功能。 有关详细信息,请参阅 应用程序兼容性 部分。
联网
.NET Framework 4.7 添加了以下与网络相关的功能:
TLS 协议的默认操作系统支持*
System.Net.Security.SslStream 和上层组件(如 HTTP、FTP 和 SMTP)使用的 TLS 堆栈允许开发人员使用操作系统支持的默认 TLS 协议。 开发人员不再需要对 TLS 版本进行硬编码。
ASP.NET
在 .NET Framework 4.7 中,ASP.NET 包含以下新功能:
对象缓存扩展性
从 .NET Framework 4.7 开始,ASP.NET 添加了一组新的 API,使开发人员能够替换内存中对象缓存和内存监视的默认 ASP.NET 实现。 如果 ASP.NET 实现不足,开发人员现在可以替换以下三个组件中的任何一个:
对象缓存存储: 通过使用新的缓存提供程序配置部分,开发人员可以使用新的 ICacheStoreProvider 接口插入 ASP.NET 应用程序的对象缓存的新实现。
内存监视: ASP.NET 中的默认内存监视器在运行接近进程配置的专用字节限制时或计算机的总可用物理 RAM 不足时通知应用程序。 接近这些限制时,就会触发通知。 对于某些应用程序,通知触发的时间过于接近配置的限制,从而无法做出有效的反应。 开发人员现在可以编写自己的内存监视器,以使用 ApplicationMonitors.MemoryMonitor 属性替换默认值。
内存限制响应: 默认情况下,ASP.NET 尝试剪裁对象缓存,并在私有字节进程限制接近时定期调用 GC.Collect。 对于某些应用程序,调用GC.Collect指令的频率或清理缓存的量可能不高效。 现在,开发人员可以通过向应用程序的内存监视器订阅 IObserver 实现来替换或补充默认行为。
Windows Communication Foundation (WCF)
Windows Communication Foundation (WCF) 添加了以下功能和更改:
能够将默认消息安全设置配置为 TLS 1.1 或 TLS 1.2
从 .NET Framework 4.7 开始,WCF 允许除了将 SSL 3.0 和 TLS 1.0 配置为默认消息安全协议之外,还可以配置 TLS 1.1 或 TLS 1.2。 这是一个选择加入设置;若要启用它,必须将以下条目添加到应用程序配置文件:
<runtime>
<AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
提高了 WCF 应用程序和 WCF 序列化的可靠性
WCF 包括许多代码更改,可消除争用条件,从而提高序列化选项的性能和可靠性。 其中包括:
- 更好地支持在调用 SocketConnection.BeginRead 和 SocketConnection.Read 时混合异步和同步代码。
- 提升了在中止与 SharedConnectionListener 和 DuplexChannelBinder 的连接时的可靠性。
- 改进了调用 FormatterServices.GetSerializableMembers(Type) 方法时序列化操作的可靠性。
- 通过调用 ChannelSynchronizer.RemoveWaiter 方法,提高了删除服务员时的可靠性。
Windows 窗体
在 .NET Framework 4.7 中,Windows 窗体改进了对高 DPI 监视器的支持。
高 DPI 支持
从面向 .NET Framework 4.7 的应用程序开始,.NET Framework 为 Windows 窗体应用程序提供高 DPI 和动态 DPI 支持。 高 DPI 支持改进了高 DPI 监视器上窗体和控件的布局和外观。 当用户更改正在运行的应用程序的 DPI 或显示比例因子时,动态 DPI 会更改窗体和控件的布局和外观。
支持高 DPI 是需要用户主动启用的功能,可以通过在应用程序配置文件中定义 <System.Windows.Forms.ConfigurationSection> 节来进行配置。 有关向 Windows 窗体应用程序添加高 DPI 支持和动态 DPI 支持的详细信息,请参阅 Windows 窗体中的
Windows Presentation Foundation (WPF)
在 .NET Framework 4.7 中,WPF 包含以下增强功能:
支持基于 Windows WM_POINTER 消息的触控/触笔堆栈
现在可以视情况使用基于 WM_POINTER 消息的触控/触笔堆栈,而不使用 Windows Ink 服务平台 (WISP)。 这是 .NET Framework 中的一项可选择启用的功能。 有关详细信息,请参阅 应用程序兼容性 部分。
WPF 打印 API 的新实现
System.Printing.PrintQueue 类中的 WPF 打印 API 调用 Windows 打印文档包 API,而不是弃用的 XPS 打印 API。 有关此更改对应用程序兼容性的影响,请参阅 应用程序兼容性 部分。
.NET Framework 4.6.2 中的新增功能
.NET Framework 4.6.2 包括以下方面的新功能:
有关添加到 .NET Framework 4.6.2 的新 API 的列表,请参阅 GitHub 上的 .NET Framework 4.6.2 API 更改。 有关 .NET Framework 4.6.2 中的功能改进和 bug 修复的列表,请参阅 GitHub 上 .NET Framework 4.6.2 更改列表。 有关详细信息,请参阅 .NET 博客中的 公告 .NET Framework 4.6.2。
ASP.NET
在 .NET Framework 4.6.2 中,ASP.NET 包含以下增强功能:
改进了对数据注释验证器中本地化错误消息的支持
数据注释验证器使您可以通过向类属性添加一个或多个特性来执行验证。 如果验证失败,该属性的 ValidationAttribute.ErrorMessage 元素定义错误消息的文本。 从 .NET Framework 4.6.2 开始,ASP.NET 可以轻松本地化错误消息。 如果出现以下问题,则会本地化错误消息:
验证属性中提供 ValidationAttribute.ErrorMessage。
资源文件存储在App_LocalResources文件夹中。
本地化资源文件的名称格式为
DataAnnotation.Localization.{
名称}.resx
,其中 名称 是文化名称,其格式为 语言代码-
国家/地区代码 或 语言代码。资源的键名称是分配给 ValidationAttribute.ErrorMessage 属性的字符串,其值为本地化的错误消息。
例如,以下数据注释属性定义无效分级的默认区域性错误消息。
public class RatingInfo
{
[Required(ErrorMessage = "The rating must be between 1 and 10.")]
[Display(Name = "Your Rating")]
public int Rating { get; set; }
}
Public Class RatingInfo
<Required(ErrorMessage = "The rating must be between 1 and 10.")>
<Display(Name = "Your Rating")>
Public Property Rating As Integer = 1
End Class
然后,可以创建一个资源文件 DataAnnotation.Localiz.fr.resx,其键是错误消息字符串,其值为本地化的错误消息。 该文件必须位于 App.LocalResources
文件夹中。 例如,下面是本地化法语(fr)语言错误消息中的键及其值:
名字 | 值 |
---|---|
分级必须介于 1 到 10 之间。 | La note doit être comprise entre 1 et 10. |
此外,数据注释本地化是可扩展的。 开发人员可以通过实现 IStringLocalizerProvider 接口来插入自己的字符串本地化程序提供程序,以将本地化字符串存储在资源文件中以外的某个位置。
会话状态存储提供程序的异步支持
ASP.NET 现在允许任务返回方法与会话状态存储提供程序一起使用,从而允许 ASP.NET 应用获得异步的可伸缩性优势。 为了支持会话状态存储提供程序的异步操作,ASP.NET 包括一个新的接口,System.Web.SessionState.ISessionStateModule,该接口继承自 IHttpModule,并允许开发人员实现自己的会话状态模块和异步会话存储提供程序。 接口的定义如下:
public interface ISessionStateModule : IHttpModule {
void ReleaseSessionState(HttpContext context);
Task ReleaseSessionStateAsync(HttpContext context);
}
Public Interface ISessionStateModule : Inherits IHttpModule
Sub ReleaseSessionState(context As HttpContext)
Function ReleaseSessionStateAsync(context As HttpContext) As Task
End Interface
此外,SessionStateUtility 类包括两个新方法,IsSessionStateReadOnly 和 IsSessionStateRequired,可用于支持异步操作。
异步对输出缓存提供程序的支持
从 .NET Framework 4.6.2 开始,任务返回方法可与输出缓存提供程序一起使用,以提供异步的可伸缩性优势。 实现这些方法的提供程序可减少 Web 服务器上的线程阻塞并提高 ASP.NET 服务的可伸缩性。
添加了以下 API 以支持异步输出缓存提供程序:
System.Web.Caching.OutputCacheProviderAsync 类,该类继承自 System.Web.Caching.OutputCacheProvider 并允许开发人员实现异步输出缓存提供程序。
OutputCacheUtility 类,提供用于配置输出缓存的帮助程序方法。
System.Web.HttpCachePolicy 类中的 18 个新方法。 其中包括 GetCacheability、GetCacheExtensions、GetETag、GetETagFromFileDependencies、GetMaxAge、GetMaxAge、GetNoStore、GetNoTransforms、GetOmitVaryStar、GetProxyMaxAge、GetRevalidation、GetUtcLastModified、GetVaryByCustom、HasSlidingExpiration和 IsValidUntilExpires。
System.Web.HttpCacheVaryByContentEncodings 类中的 2 个新方法:GetContentEncodings 和 SetContentEncodings。
System.Web.HttpCacheVaryByHeaders 类中的 2 个新方法:GetHeaders 和 SetHeaders。
System.Web.HttpCacheVaryByParams 类中的 2 个新方法:GetParams 和 SetParams。
System.Web.Caching.AggregateCacheDependency 类中的 GetFileDependencies 方法。
字符类别
.NET Framework 4.6.2 中的字符根据 Unicode 标准版本 8.0.0进行分类。 在 .NET Framework 4.6 和 .NET Framework 4.6.1 中,字符根据 Unicode 6.3 字符类别进行分类。
对 Unicode 8.0 的支持仅限于 CharUnicodeInfo 类的字符分类以及依赖它的类型和方法。 其中包括 StringInfo 类、重载的 Char.GetUnicodeCategory 方法和 .NET Framework 正则表达式引擎识别的字符类。 字符和字符串比较和排序不受此更改的影响,并且继续依赖于基础操作系统,或者,在 Windows 7 系统上,依赖于 .NET Framework 提供的字符数据。
有关字符类别从 Unicode 6.0 更改为 Unicode 7.0 的更改,请参阅 Unicode 联盟网站上的 Unicode 标准,版本 7.0.0。 有关从 Unicode 7.0 更改为 Unicode 8.0 的更改,请参阅 Unicode 联盟网站上的 Unicode 标准版本 8.0.0。
密码学
对包含 FIPS 186-3 DSA 的 X509 证书的支持
.NET Framework 4.6.2 增加了对 DSA (数字签名算法) X509 证书的支持,其密钥超过 FIPS 186-2 1024 位限制。
除了支持 FIPS 186-3 的更大密钥大小外,.NET Framework 4.6.2 还允许使用 SHA-2 系列哈希算法(SHA256、SHA384 和 SHA512)计算签名。 新的 System.Security.Cryptography.DSACng 类提供 FIPS 186-3 支持。
为了与.NET Framework 4.6中RSA类和.NET Framework 4.6.1中ECDsa类的最新更改保持一致,.NET Framework 4.6.2中的DSA抽象基类添加了额外的方法,允许调用方无需强制转换即可使用此功能。 可以调用 DSACertificateExtensions.GetDSAPrivateKey 扩展方法对数据进行签名,如以下示例所示。
public static byte[] SignDataDsaSha384(byte[] data, X509Certificate2 cert)
{
using (DSA dsa = cert.GetDSAPrivateKey())
{
return dsa.SignData(data, HashAlgorithmName.SHA384);
}
}
Public Shared Function SignDataDsaSha384(data As Byte(), cert As X509Certificate2) As Byte()
Using DSA As DSA = cert.GetDSAPrivateKey()
Return DSA.SignData(data, HashAlgorithmName.SHA384)
End Using
End Function
可以调用 DSACertificateExtensions.GetDSAPublicKey 扩展方法来验证签名的数据,如以下示例所示。
public static bool VerifyDataDsaSha384(byte[] data, byte[] signature, X509Certificate2 cert)
{
using (DSA dsa = cert.GetDSAPublicKey())
{
return dsa.VerifyData(data, signature, HashAlgorithmName.SHA384);
}
}
Public Shared Function VerifyDataDsaSha384(data As Byte(), signature As Byte(), cert As X509Certificate2) As Boolean
Using dsa As DSA = cert.GetDSAPublicKey()
Return dsa.VerifyData(data, signature, HashAlgorithmName.SHA384)
End Using
End Function
提高了 ECDiffieHellman 密钥派生例程的输入的清晰度
.NET Framework 3.5 添加了对椭圆曲线 Diffie-Hellman 密钥协议的支持,其中包含三个不同的密钥派生函数 (KDF) 例程。 对例程和例程本身的输入是通过 ECDiffieHellmanCng 对象的属性配置的。 但由于不是每个例程都会读取每个输入属性,因此过去很有可能对开发人员造成了困扰。
若要在 .NET Framework 4.6.2 中解决此问题,已将以下三种方法添加到 ECDiffieHellman 基类,以便更清楚地表示这些 KDF 例程及其输入:
ECDiffieHellman 方法 | 描述 |
---|---|
DeriveKeyFromHash(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[]) | 通过公式派生密钥材料 HASH(secretPrepend || x || secretAppend) HASH(secretPrepend OrElse x OrElse secretAppend) 其中,x 是 EC Diffie-Hellman 算法的计算结果。 |
DeriveKeyFromHmac(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[], Byte[]) | 使用下面的公式派生密钥材料 HMAC(hmacKey, secretPrepend || x || secretAppend) HMAC(hmacKey, secretPrepend OrElse x OrElse secretAppend) 其中,x 是 EC Diffie-Hellman 算法的计算结果。 |
DeriveKeyTls(ECDiffieHellmanPublicKey, Byte[], Byte[]) | 使用 TLS 伪随机函数 (PRF) 派生算法派生密钥材料。 |
支持持久密钥对称加密
Windows 加密库(CNG)增加了对存储持久对称密钥和使用硬件存储对称密钥的支持,而 .NET Framework 4.6.2 使开发人员能够使用此功能。 因为密钥名和密钥提供程序的概念是特定于实现的,所以使用此功能要求使用具体实现类型(而不是首选出厂方法)的构造函数(例如,调用 Aes.Create
)。
AES(AesCng)和 3DES(TripleDESCng)算法存在持久密钥对称加密支持。 例如:
public static byte[] EncryptDataWithPersistedKey(byte[] data, byte[] iv)
{
using (Aes aes = new AesCng("AesDemoKey", CngProvider.MicrosoftSoftwareKeyStorageProvider))
{
aes.IV = iv;
// Using the zero-argument overload is required to make use of the persisted key
using (ICryptoTransform encryptor = aes.CreateEncryptor())
{
if (!encryptor.CanTransformMultipleBlocks)
{
throw new InvalidOperationException("This is a sample, this case wasn't handled...");
}
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
}
}
Public Shared Function EncryptDataWithPersistedKey(data As Byte(), iv As Byte()) As Byte()
Using Aes As Aes = New AesCng("AesDemoKey", CngProvider.MicrosoftSoftwareKeyStorageProvider)
Aes.IV = iv
' Using the zero-argument overload Is required to make use of the persisted key
Using encryptor As ICryptoTransform = Aes.CreateEncryptor()
If Not encryptor.CanTransformMultipleBlocks Then
Throw New InvalidOperationException("This is a sample, this case wasn't handled...")
End If
Return encryptor.TransformFinalBlock(data, 0, data.Length)
End Using
End Using
End Function
对 SHA-2 哈希的 SignedXml 支持
.NET Framework 4.6.2 为 RSA-SHA256、RSA-SHA384 和 RSA-SHA512 PKCS#1 签名方法、SHA256、SHA384 和 SHA512 引用摘要算法的 SignedXml 类添加了支持。
URI 常量都在 SignedXml上暴露:
SignedXml 字段 | 恒定的 |
---|---|
XmlDsigSHA256Url | "http://www.w3.org/2001/04/xmlenc#sha256" |
XmlDsigRSASHA256Url | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" |
XmlDsigSHA384Url | "http://www.w3.org/2001/04/xmldsig-more#sha384" |
XmlDsigRSASHA384Url | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" |
XmlDsigSHA512Url | "http://www.w3.org/2001/04/xmlenc#sha512" |
XmlDsigRSASHA512Url | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" |
任何将自定义 SignatureDescription 处理程序注册到 CryptoConfig 以添加对这些算法的支持的程序将继续像过去一样正常运行,但由于现在存在平台默认值,因此不再需要 CryptoConfig 注册。
SqlClient
适用于 SQL Server 的 .NET Framework 数据提供程序(System.Data.SqlClient)包括 .NET Framework 4.6.2 中的以下新功能:
Azure SQL 数据库的连接池和超时
启用连接池后,如果发生超时或其他登录错误,将缓存这个异常,并在随后的连接尝试中,在接下来的5秒到1分钟内抛出缓存的异常。 有关详细信息,请参阅 SQL Server 连接池 (ADO.NET)。
在连接到 Azure SQL 数据库时,这种行为是不可取的,因为连接尝试可能会因暂时性错误而失败,而这些错误通常能迅速恢复。 为更好地优化连接重试体验,会在与 Azure SQL 数据库连接失败时删除连接池阻塞期行为。
添加新的 PoolBlockingPeriod
关键字使你可以选择最适合应用的阻止期。 值包括:
已禁用连接到 Azure SQL 数据库的应用程序的连接池阻塞期,并且启用了连接到任何其他 SQL Server 实例的应用程序的连接池阻塞期。 这是默认值。 如果服务器终结点名称以下列任一结尾,则它们被视为 Azure SQL 数据库:
.database.windows.net
.database.chinacloudapi.cn
.database.usgovcloudapi.net
.database.cloudapi.de
连接池阻塞期始终处于启用状态。
连接池阻塞期始终处于禁用状态。
Always Encrypted 的增强功能
SQLClient 为 Always Encrypted 引入了两项增强功能:
为了提高针对加密数据库列的参数化查询的性能,现在会缓存查询参数的加密元数据。 如果将 SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled 属性设置为
true
(即默认值),如果多次调用同一查询,则客户端仅从服务器检索参数元数据一次。密钥缓存中的列加密密钥条目现在将在可配置的时间间隔后被移除,该间隔可通过 SqlConnection.ColumnEncryptionKeyCacheTtl 属性进行设置。
Windows Communication Foundation
在 .NET Framework 4.6.2 中,Windows Communication Foundation 已在以下方面得到增强:
使用 CNG 对存储的证书的 WCF 传输安全支持
WCF 传输安全性支持使用 Windows 加密库(CNG)存储的证书。 在 .NET Framework 4.6.2 中,此支持仅限于使用具有长度不超过 32 位的公钥的证书。 当应用程序面向 .NET Framework 4.6.2 时,此功能默认处于打开状态。
对于目标是 .NET Framework 4.6.1 及更早版本,但在 .NET Framework 4.6.2 上运行的应用程序,可以通过在 app.config 或 web.config 文件的 <运行时> 部分加入以下行来启用此功能。
<AppContextSwitchOverrides
value="Switch.System.IdentityModel.DisableCngCertificates=false"
/>
也可以使用如下所示的代码以编程方式完成此操作:
private const string DisableCngCertificates = @"Switch.System.IdentityModel.DisableCngCertificates";
AppContext.SetSwitch(disableCngCertificates, false);
Const DisableCngCertificates As String = "Switch.System.IdentityModel.DisableCngCertificates"
AppContext.SetSwitch(disableCngCertificates, False)
通过 DataContractJsonSerializer 类更好地支持多个夏令时调整规则
客户可以使用应用程序配置设置来确定 DataContractJsonSerializer 类是否支持单个时区的多个调整规则。 这是一项可以选择使用的功能。 若要启用它,请将以下设置添加到 app.config 文件:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Runtime.Serialization.DoNotUseTimeZoneInfo=false" />
</runtime>
启用此功能后,DataContractJsonSerializer 对象使用 TimeZoneInfo 类型而不是 TimeZone 类型反序列化日期和时间数据。 TimeZoneInfo 支持多个调整规则,从而能够处理历史时区数据;TimeZone 不。
有关 TimeZoneInfo 结构和时区调整的详细信息,请参阅 时区概述。
NetNamedPipeBinding 最佳匹配
WCF 包含可以在客户端应用程序上设置以确保它们始终连接到服务的新应用设置,该服务在与它们请求的最匹配的 URI 上进行侦听。 将此应用设置设置为 false
(默认值)时,客户端可以使用 NetNamedPipeBinding 尝试连接到服务,该服务在是所请求 URI 的子字符串的 URI 上进行侦听。
例如,一个客户端尝试连接到在 net.pipe://localhost/Service1
处进行侦听的服务,但该计算机上使用管理员特权运行的另一个服务在 net.pipe://localhost
处进行侦听。 将此应用设置设置为 false
,客户端将尝试连接到错误的服务。 将应用设置设置为 true
后,客户端将始终连接到最佳匹配服务。
注意
使用 NetNamedPipeBinding 的客户端根据服务的基址(如果存在)而不是完整的终结点地址查找服务。 为了确保此设置始终有效,服务应使用唯一的基址。
若要启用此更改,请将以下应用设置添加到客户端应用程序的 App.config 或 Web.config 文件:
<configuration>
<appSettings>
<add key="wcf:useBestMatchNamedPipeUri" value="true" />
</appSettings>
</configuration>
SSL 3.0 不是默认协议
将 NetTcp 与传输安全性和凭据类型的证书配合使用时,SSL 3.0 不再是用于协商安全连接的默认协议。 在大多数情况下,不应对现有应用造成任何影响,因为 NETTcp 的协议列表中包含 TLS 1.0。 所有现有客户端应该能够至少使用 TLS 1.0 协商连接。 如果需要 Ssl3,请使用以下配置机制之一将其添加到协商协议列表中。
<netTcpBinding> 部分的 <transport> 部分
Windows Presentation Foundation (WPF)
在 .NET Framework 4.6.2 中,Windows Presentation Foundation 已在以下方面进行了增强:
组排序
使用 CollectionView 对象对数据进行分组的应用程序现在可以显式声明如何对组进行排序。 显式排序解决了应用动态添加或删除组时或者更改分组中涉及的项属性值时发生的非直观的排序问题。 它还可通过将分组属性比较从完整集合排序移动到组排序来改善组创建过程的性能。
为了支持组排序,新的 GroupDescription.SortDescriptions 和 GroupDescription.CustomSort 属性介绍了如何对 GroupDescription 对象生成的组的集合进行排序。 这类似于同名 ListCollectionView 属性描述如何对数据项进行排序的方式。
PropertyGroupDescription 类的两个新的静态属性(CompareNameAscending 和 CompareNameDescending)可用于最常见的情况。
例如,以下 XAML 按年龄对数据进行分组、按升序对年龄组进行排序,并按姓氏对每个年龄组中的项目进行分组。
<GroupDescriptions>
<PropertyGroupDescription
PropertyName="Age"
CustomSort=
"{x:Static PropertyGroupDescription.CompareNamesAscending}"/>
</PropertyGroupDescription>
</GroupDescriptions>
<SortDescriptions>
<SortDescription PropertyName="LastName"/>
</SortDescriptions>
触控键盘支持
在可采用文本输入的控件接收触摸输入时,通过自动调用和解除 Windows 10 中的触控键盘,可在 WPF 应用程序中启用焦点跟踪。
在 .NET framework 的早期版本中,WPF 应用程序不能在不禁用 WPF 笔/触摸手势支持的情况下选择加入焦点跟踪。 因此,WPF 应用程序必须选择完整的 WPF 触摸支持或依赖于 Windows 鼠标提升。
按监视器 DPI
为了支持最近激增的 WPF 应用程序高 DPI 和混合 DPI 环境,.NET Framework 4.6.2 中的 WPF 启用了按监视器 DPI 感知。 关于如何使您的 WPF 应用程序对每个监视器的 DPI 感知的更多信息,请参阅 GitHub 上的 示例和开发者指南。
在早期版本的 .NET Framework 中,WPF 应用具有系统 DPI 感知性。 换句话说,应用程序的 UI 会根据应用运行时的监视器的 DPI 由操作系统适当缩放。
对于在 .NET Framework 4.6.2 下运行的应用程序,您可以通过在应用程序配置文件的 <运行时> 部分添加配置语句来禁用 WPF 应用程序中的每监视器 DPI 更改,如下所示:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false"/>
</runtime>
Windows Workflow Foundation (WF)
在 .NET Framework 4.6.2 中,Windows Workflow Foundation 已在以下区域中得到增强:
在重新托管的 WF 设计器中支持 C# 表达式和 IntelliSense
从 .NET Framework 4.5 开始,WF 支持 Visual Studio Designer 和代码工作流中的 C# 表达式。 重新托管的工作流设计器是 WF 的关键功能,它允许工作流设计器位于 Visual Studio 外部的应用程序(例如,在 WPF 中)。 Windows Workflow Foundation 提供在重新托管的工作流设计器中支持 C# 表达式和 IntelliSense 的功能。 有关详细信息,请参阅 Windows Workflow Foundation 博客。
Availability of IntelliSense when a customer rebuilds a workflow project from Visual Studio
在 4.6.2 之前的 .NET Framework 版本中,当客户从 Visual Studio 重新生成工作流项目时,WF Designer IntelliSense 会中断。 项目生成成功时,设计器上找不到工作流类型,缺少工作流类型的 IntelliSense 警告将显示在 错误列表 窗口中。 .NET Framework 4.6.2 解决了此问题,并使 IntelliSense 可用。
启用了工作流跟踪的工作流 V1 应用程序现以 FIPS 模式运行
启用 FIPS 符合性模式的计算机现在可以成功运行工作流版本 1 样式的应用程序,并启用工作流跟踪。 若要启用此方案,必须对 app.config 文件进行以下更改:
<add key="microsoft:WorkflowRuntime:FIPSRequired" value="true" />
如果未启用此方案,则运行应用程序将继续生成异常,并显示消息“此实现不是 Windows 平台 FIPS 验证加密算法的一部分”。
结合使用动态更新和 Visual Studio 工作流设计器时的工作流改进
工作流设计器、流程图活动设计器和其他工作流活动设计器现在已成功加载并显示调用 DynamicUpdateServices.PrepareForUpdate 方法后已保存的工作流。 在 .NET Framework 4.6.2 之前的 .NET Framework 版本中,在 Visual Studio 中加载 XAML 文件以获取在调用 DynamicUpdateServices.PrepareForUpdate 后保存的工作流可能会导致以下问题:
工作流设计器无法正确加载 XAML 文件(当 ViewStateData.Id 位于行尾时)。
流程图活动设计器或其他工作流活动设计器可以显示其默认位置中的所有对象,而不是附加的属性值。
ClickOnce
ClickOnce 已更新,以支持 TLS 1.1 和 TLS 1.2,除了它已经支持的 1.0 协议。 ClickOnce 会自动检测所需的协议;启用 TLS 1.1 和 1.2 支持不需要 ClickOnce 应用程序中的额外步骤。
将 Windows 窗体和 WPF 应用转换为 UWP 应用
Windows 现在提供将现有 Windows 桌面应用(包括 WPF 和 Windows 窗体应用)引入通用 Windows 平台(UWP)的功能。 此技术起到桥梁作用,允许您将现有代码库逐步迁移到 UWP,使您的应用可以覆盖所有 Windows 10 设备。
转换后的桌面应用程序获得了类似于 UWP 应用的应用标识,使得这些应用能够访问 UWP API,以启用动态磁贴和通知等功能。 应用继续像以前一样运行,并作为完全信任应用运行。 转换应用后,可将应用容器进程添加到现有的完全信任进程,以添加自适应用户界面。 将所有功能移动到应用容器进程时,可以删除完全信任过程,并且所有 Windows 10 设备都可以使用新的 UWP 应用。
调试改进
非托管调试 API 在 .NET Framework 4.6.2 中得到了增强,使其在引发 NullReferenceException 时能够执行额外的分析,以确定单个源代码行中哪个变量是 null
。 为了支持此方案,已将以下 API 添加到非托管调试 API。
ICorDebugCode4、ICorDebugVariableHome和 ICorDebugVariableHomeEnum 接口,公开了托管变量的本地存储位置。 这使调试器能够在 NullReferenceException 发生时执行某些代码流分析并逆向工作,以确定对应于为
null
的本机位置的托管变量。ICorDebugType2::GetTypeID 方法提供 ICorDebugType 到 COR_TYPEID的映射,这样调试器就可以在没有 ICorDebugType 实例的情况下获取 COR_TYPEID。 然后,可以使用 COR_TYPEID 上的现有 API 来确定类型的类布局。
.NET Framework 4.6.1 中的新增功能
.NET Framework 4.6.1 包括以下方面的新功能:
有关 .NET Framework 4.6.1 的详细信息,请参阅以下主题:
4.6.1 中的应用程序兼容性
.NET Framework API 差异(在 GitHub 上)
加密:支持包含 ECDSA 的 X509 证书
.NET Framework 4.6 添加了对 X509 证书的 RSACng 支持。 .NET Framework 4.6.1 添加了对 ECDSA(椭圆曲线数字签名算法)X509 证书的支持。
ECDSA 提供更好的性能,并且作为一种加密算法,比 RSA 更加安全。在关注传输层安全性(TLS)性能和可扩展性的问题上,ECDSA 是一个极佳的选择。 .NET Framework 实现将调用包装到现有的 Windows 功能中。
以下示例代码演示如何使用 .NET Framework 4.6.1 中包含的 ECDSA X509 证书的新支持为字节流生成签名是多么容易。
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
public class Net461Code
{
public static byte[] SignECDsaSha512(byte[] data, X509Certificate2 cert)
{
using (ECDsa privateKey = cert.GetECDsaPrivateKey())
{
return privateKey.SignData(data, HashAlgorithmName.SHA512);
}
}
public static byte[] SignECDsaSha512(byte[] data, ECDsa privateKey)
{
return privateKey.SignData(data, HashAlgorithmName.SHA512);
}
}
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Public Class Net461Code
Public Shared Function SignECDsaSha512(data As Byte(), cert As X509Certificate2) As Byte()
Using privateKey As ECDsa = cert.GetECDsaPrivateKey()
Return privateKey.SignData(data, HashAlgorithmName.SHA512)
End Using
End Function
Public Shared Function SignECDsaSha512(data As Byte, privateKey As ECDsa) As Byte()
Return privateKey.SignData(data, HashAlgorithmName.SHA512)
End Function
End Class
这与在 .NET Framework 4.6 中生成签名所需的代码形成鲜明对比。
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
public class Net46Code
{
public static byte[] SignECDsaSha512(byte[] data, X509Certificate2 cert)
{
// This would require using cert.Handle and a series of p/invokes to get at the
// underlying key, then passing that to a CngKey object, and passing that to
// new ECDsa(CngKey). It's a lot of work.
throw new Exception("That's a lot of work...");
}
public static byte[] SignECDsaSha512(byte[] data, ECDsa privateKey)
{
// This way works, but SignData probably better matches what you want.
using (SHA512 hasher = SHA512.Create())
{
byte[] signature1 = privateKey.SignHash(hasher.ComputeHash(data));
}
// This might not be the ECDsa you got!
ECDsaCng ecDsaCng = (ECDsaCng)privateKey;
ecDsaCng.HashAlgorithm = CngAlgorithm.Sha512;
return ecDsaCng.SignData(data);
}
}
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Public Class Net46Code
Public Shared Function SignECDsaSha512(data As Byte(), cert As X509Certificate2) As Byte()
' This would require using cert.Handle and a series of p/invokes to get at the
' underlying key, then passing that to a CngKey object, and passing that to
' new ECDsa(CngKey). It's a lot of work.
Throw New Exception("That's a lot of work...")
End Function
Public Shared Function SignECDsaSha512(data As Byte(), privateKey As ECDsa) As Byte()
' This way works, but SignData probably better matches what you want.
Using hasher As SHA512 = SHA512.Create()
Dim signature1 As Byte() = privateKey.SignHash(hasher.ComputeHash(data))
End Using
' This might not be the ECDsa you got!
Dim ecDsaCng As ECDsaCng = CType(privateKey, ECDsaCng)
ecDsaCng.HashAlgorithm = CngAlgorithm.Sha512
Return ecDsaCng.SignData(data)
End Function
End Class
ADO.NET
已将以下内容添加到 ADO.NET:
针对硬件保护密钥的 Always Encrypted 支持
ADO.NET 现在支持在硬件安全模块(HSM)中原生存储 Always Encrypted 的列主密钥。 借助此支持,客户可以利用 HSM 中存储的非对称密钥,而无需编写自定义列主密钥存储提供程序并在应用程序中注册它们。
客户需要在应用服务器或客户端计算机上安装 HSM 供应商提供的 CSP 提供程序或 CNG 密钥存储提供程序,才能访问受 HSM 中存储的列主密钥保护的 Always Encrypted 数据。
改进了 AlwaysOn 的 MultiSubnetFailover 连接行为
SqlClient 现在为 AlwaysOn 高可用性组(AG)自动提供更快的连接。 它以透明方式检测应用程序是否连接到其他子网上的 AlwaysOn 可用性组(AG),并快速发现当前活动服务器并提供与服务器的连接。 在此版本之前,应用程序必须设置连接字符串以包含 "MultisubnetFailover=true"
,以指示它正在连接到 AlwaysOn 可用性组。 如果不将连接关键字设置为 true
,应用程序在连接到 AlwaysOn 可用性组时可能会遇到超时。 使用此版本时,应用程序无需再将 MultiSubnetFailover 设置为 true
。 有关 SqlClient 对 AlwaysOn 可用性组支持的更多信息,请参阅 SqlClient 对高可用性和灾难恢复的支持。
Windows Presentation Foundation (WPF)
Windows Presentation Foundation 包括多项改进和更改。
改进了性能
在 .NET Framework 4.6.1 中,已修复触摸事件触发的延迟问题。 此外在快速输入过程中,在 RichTextBox 控件中输入不再占用呈现线程。
拼写检查改进
WPF 中的拼写检查器已在 Windows 8.1 及更高版本上进行了更新,以利用操作系统对其他语言进行拼写检查的支持。 Windows 8.1 之前的 Windows 版本中的功能没有变化。
与以前版本的 .NET Framework 一样,通过按以下顺序查找信息来检测 TextBox 控件或 RichTextBox 块的语言:
xml:lang
(如果存在)。当前输入语言。
当前文化。
有关 WPF 中语言支持的更多信息,请参阅关于 .NET Framework 4.6.1 功能的 WPF 博客文章。
针对每用户自定义词典的附加支持
在 .NET Framework 4.6.1 中,WPF 可识别全局注册的自定义词典。 除了能够针对每个控件注册它们,还提供了此功能。
在早期版本的 WPF 中,自定义词典无法识别排除的单词和自动更正列表。 在 Windows 8.1 和 Windows 10 上,通过使用可以置于 %AppData%\Microsoft\Spelling\<language tag>
目录下的文件来支持它们。 以下规则适用于这些文件:
这些文件的扩展名应为 .dic(对于添加的单词)、.exc(对于排除的单词),或 .acl(对于自动更正)。
这些文件应为以字节顺序标记(BOM)开头的 UTF-16 LE 纯文本。
每行应包含一个单词(在添加和排除的单词列表中),或一个由竖线(“|”)分隔的自动更正配对单词(在“自动更正”词列表中)。
这些文件被视为只读文件,系统不会对其进行修改。
注意
WPF 拼写检查 API 不支持这些新的文件格式,并且应用程序中提供给 WPF 的自定义词典应继续使用 .lex 文件。
示例
在 Microsoft/WPF-Samples GitHub 存储库中有许多 WPF 示例。 可通过向我们发送拉取请求或建立 GitHub 问题来帮助我们改进示例。
DirectX 扩展
WPF 包括一个 NuGet 包,它提供 D3DImage 的新实现,使你可以轻松地与 DX10 和 Dx11 内容进行互操作。 此包的代码已开放源代码,在 GitHub 上提供。
Windows Workflow Foundation:事务
Transaction.EnlistPromotableSinglePhase 方法现在可以使用 MSDTC 以外的分布式事务管理器来提升事务。 可通过将 GUID 事务提升程序标识符指定为新的 Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification, Guid) 重载来实现此目的。 如果此操作成功,则会对事务的功能施加一些限制。 非 MSDTC 事务提升程序登记之后,以下方法会引发 TransactionPromotionException,因为这些方法需要提升到 MSDTC:
非 MSDTC 事务提升程序登记之后,它必须使用它定义的协议来用于将来的持久登记。 事务提升程序的 Guid 可以使用 PromoterType 属性来获取。 当事务提升时,事务提升程序会提供表示提升令牌的 Byte 数组。 应用程序可以使用 GetPromotedToken 方法获取非 MSDTC 提升事务的提升令牌。
新 Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification, Guid) 重载的用户必须遵循特定调用序列,才能使提升操作成功完成。 这些规则记录在方法的文档中。
分析
非托管分析 API 在以下方面得到了增强:
优化对 ICorProfilerInfo7 接口中 PDB 访问的支持。
在 ASP.NET Core 中,使用 Roslyn 在内存中编译程序集的做法变得更加普遍。 对于创建分析工具的开发人员,这意味着以前在磁盘上序列化的 PDB 可能不再存在。 探查器工具通常使用 PDB 将代码映射回源行,以便执行代码覆盖率或逐行性能分析等任务。 ICorProfilerInfo7 接口现在包括两个新方法:ICorProfilerInfo7::GetInMemorySymbolsLength 和 ICorProfilerInfo7::ReadInMemorySymbols,以便为这些探查器工具提供对内存中 PDB 数据的访问权限, 通过使用新 API,探查器可以将内存中 PDB 的内容作为字节数组获取,然后将其处理或序列化为磁盘。
使用 ICorProfiler 接口可更好地检测。
使用
ICorProfiler
API 的 ReJit 功能进行动态检测的分析器现在可以修改某些元数据。 以前,这些工具可以随时检测 IL,但只能在模块加载时修改元数据。 因为 IL 引用元数据,所以这会限制可以进行的检测的种类。 我们通过添加 ICorProfilerInfo7::ApplyMetaData 方法支持模块加载后的元数据编辑子集,尤其是通过添加新的AssemblyRef
、TypeRef
、TypeSpec
、MemberRef
、MemberSpec
和UserString
记录,解除其中一些限制。 通过此更改可以进行范围广得多的动态检测。
本机映像生成器 (NGEN) PDB
跨计算机事件跟踪允许客户在计算机 A 上分析程序,并使用计算机 B 上的源行映射查看分析数据。使用早期版本的 .NET Framework,用户会将分析计算机中的所有模块和本机映像复制到包含 IL PDB 的分析计算机,以创建源到本机映射。 虽然当文件相对较小(例如手机应用程序)时,此过程可能很顺利,但文件在桌面系统上可能非常大,需要大量时间进行复制。
使用 Ngen PDB,NGen 可以创建包含 IL 到本机映射的 PDB,而无需依赖于 IL PDB。 在我们的跨计算机事件跟踪方案中,只需将计算机 A 生成的本机映像 PDB 复制到计算机 B,并使用调试接口访问 API 读取 IL PDB 的源到 IL 映射和本机映像 PDB 的 IL 到本机映射。 合并这两个映射可提供源到本地映射。 由于本机映像 PDB 比所有模块和本机映像都小得多,因此从计算机 A 复制到计算机 B 的过程要快得多。
.NET 2015 中的新增功能
.NET 2015 引入了 .NET Framework 4.6 和 .NET Core。 一些新功能适用于这两项,其他功能特定于 .NET Framework 4.6 或 .NET Core。
ASP.NET Core
.NET 2015 包括 ASP.NET Core,这是用于构建现代基于云的应用的精简 .NET 实现。 ASP.NET Core 是模块化的,因此只能包含应用程序中所需的这些功能。 它可以托管在 IIS 上,也可以在自定义进程中自承载,并且可以在同一服务器上运行具有不同版本的 .NET Framework 的应用。 它包括专为云部署设计的新环境配置系统。
MVC、Web API 和网页统一到名为 MVC 6 的单个框架中。 可通过 Visual Studio 2015 或更高版本中的工具生成 ASP.NET Core 应用。 现有应用程序将在新的 .NET Framework 上运行;但是,若要生成使用 MVC 6 或 SignalR 3 的应用,必须在 Visual Studio 2015 或更高版本中使用项目系统。
有关详细信息,请参阅 ASP.NET Core。
ASP.NET 更新
基于任务的 API,用于异步响应刷新
ASP.NET 现在提供一个基于任务的简单 API HttpResponse.FlushAsync 用于异步响应刷新,它允许通过使用你的语言的
async/await
支持来异步刷新响应。模型绑定支持 Task 返回方法
在 .NET Framework 4.5 中,ASP.NET 添加了模型绑定功能,该功能支持在 Web 窗体页和用户控件中实现基于 CRUD 的数据操作的可扩展、以代码为中心的方法。 模型绑定系统现在支持返回 Task的模型绑定方法。 此功能允许 Web 窗体开发人员在使用较新版本的 ORM(包括实体框架)时,通过数据绑定系统的简易性获得异步带来的可伸缩性优势。
异步模型绑定由
aspnet:EnableAsyncModelBinding
配置设置控制。<appSettings> <add key=" aspnet:EnableAsyncModelBinding" value="true|false" /> </appSettings>
在目标 .NET Framework 4.6 的应用上,默认为
true
。 在 .NET Framework 4.6 上运行但以早期版本为目标的应用程序中,默认值为false
。 可以通过将配置设置设置为true
来启用它。HTTP/2 支持(Windows 10)
HTTP/2 是 HTTP 协议的新版本,可提供更好的连接利用率(客户端和服务器之间的往返次数更少),从而降低用户的延迟网页加载。 网页(与服务相比)最受益于 HTTP/2,因为协议针对作为单个体验的一部分被请求的多个资源进行了优化。 HTTP/2 支持已添加到 .NET Framework 4.6 中的 ASP.NET。 由于网络功能存在于多个层中,因此 Windows、IIS 和 ASP.NET 中需要新功能才能启用 HTTP/2。 必须在 Windows 10 上运行才能将 HTTP/2 与 ASP.NET 配合使用。
默认情况下,使用 System.Net.Http.HttpClient API 的 Windows 10 通用 Windows 平台(UWP)应用也支持并启用 HTTP/2。
为了提供一种方法来使用 ASP.NET 应用程序中的 PUSH_PROMISE 功能,已向 HttpResponse 类添加了一种具有两个重载(PushPromise(String) 和 PushPromise(String, String, NameValueCollection))的新方法。
注意
虽然 ASP.NET Core 支持 HTTP/2,但尚未添加对 PUSH PROMISE 功能的支持。
浏览器和 Web 服务器(Windows 上的 IIS)执行所有工作。 无需为用户执行任何繁重操作。
大多数 主要浏览器都支持 HTTP/2,因此,如果服务器支持 HTTP/2,用户可能会从 HTTP/2 支持中受益。
对令牌绑定协议 的支持
Microsoft和谷歌一直在合作采用新的身份验证方法,称为 令牌绑定协议。 前提是,身份验证令牌(在浏览器缓存中)可以被盗,供罪犯用来访问其他安全资源(例如,银行帐户),而无需密码或任何其他特权知识。 新协议旨在缓解此问题。
令牌绑定协议将在 Windows 10 中作为浏览器功能实现。 ASP.NET 应用将参与协议,以便验证身份验证令牌是否合法。 客户端和服务器实现建立协议指定的端到端保护。
随机字符串哈希算法 .NET Framework 4.5 引入了 随机字符串哈希算法。 但是,ASP.NET 不支持它,因为某些 ASP.NET 功能依赖于稳定的哈希代码。 在 .NET Framework 4.6 中,现在支持随机字符串哈希算法。 若要启用此功能,请使用
aspnet:UseRandomizedStringHashAlgorithm
配置设置。<appSettings> <add key="aspnet:UseRandomizedStringHashAlgorithm" value="true|false" /> </appSettings>
ADO.NET
ADO .NET 现在支持 SQL Server 2016 中提供的 Always Encrypted 功能。 使用 Always Encrypted,SQL Server 可以对加密数据执行操作,并且所有加密密钥都与客户受信任的环境内的应用程序一起驻留,而不是驻留在服务器上。 Always Encrypted 保护客户数据,因此 DBA 无法访问纯文本数据。 加密和解密数据在驱动程序级别以透明方式进行,尽量减少对现有应用程序所做的更改。 有关详细信息,请参阅 Always Encrypted(数据库引擎) 和 Always Encrypted(客户端开发)。
托管代码的 64 位 JIT 编译器
.NET Framework 4.6 引入了一个代号为 RyuJIT 的新版本 64 位 JIT 编译器。 新的 64 位编译器在较旧的 64 位 JIT 编译器上提供显著的性能改进。 为在 .NET Framework 4.6 上运行的 64 位进程启用新的 64 位编译器。 如果应用编译为 64 位或 AnyCPU 并在 64 位操作系统上运行,则应用将在 64 位进程中运行。 尽管在向新的编译器过渡时已尽量做到透明,但行为的变化仍有可能发生。
新的 64 位 JIT 编译器还包括硬件 SIMD 加速功能,结合 System.Numerics 命名空间中支持 SIMD 的类型使用时,可以获得良好的性能提升。
程序集加载程序改进
程序集加载程序现在通过在加载相应的 NGEN 映像后卸载 IL 程序集,更有效地使用内存。 此更改会减少虚拟内存,这对大型 32 位应用(如 Visual Studio)特别有利,还节省物理内存。
基类库更改
许多新的 API 已添加到 .NET Framework 4.6,以启用关键方案。 其中包括以下更改和新增内容:
IReadOnlyCollection<T> 实现
其他集合实现 IReadOnlyCollection<T>,例如 Queue<T> 和 Stack<T>。
CultureInfo.CurrentCulture 和 CultureInfo.CurrentUICulture
CultureInfo.CurrentCulture 和 CultureInfo.CurrentUICulture 属性现在是读写而不是只读。 如果将新的 CultureInfo 对象分配给这些属性,则由
Thread.CurrentThread.CurrentCulture
属性定义的当前线程区域性和由Thread.CurrentThread.CurrentUICulture
属性定义的当前 UI 线程区域性也会更改。垃圾回收 (GC) 增强功能
GC 类现在包括 TryStartNoGCRegion 和 EndNoGCRegion 方法,这些方法允许在执行关键路径期间禁止垃圾回收。
GC.Collect(Int32, GCCollectionMode, Boolean, Boolean) 方法的新重载允许你控制小型对象堆和大型对象堆是否均扫频和压缩或仅扫频。
启用了 SIMD 的类型
System.Numerics 命名空间现在包括许多已启用 SIMD 的类型,例如 Matrix3x2、Matrix4x4、Plane、Quaternion、Vector2、Vector3和 Vector4。
由于新的 64 位 JIT 编译器还包括硬件 SIMD 加速功能,因此在将启用了 SIMD 的类型与新的 64 位 JIT 编译器结合使用时,性能特别显著。
加密更新
System.Security.Cryptography API 正在更新以支持 Windows CNG 加密 API。 早期版本的 .NET Framework 完全依赖于 早期版本的 Windows 加密 API, 作为 System.Security.Cryptography 实现的基础。 我们曾请求支持 CNG API,因为它支持 新式加密算法,这对某些类别的应用非常重要。
.NET Framework 4.6 包括以下支持 Windows CNG 加密 API 的新增强功能:
X509 证书(
System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPublicKey(System.Security.Cryptography.X509Certificates.X509Certificate2)
和System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(System.Security.Cryptography.X509Certificates.X509Certificate2)
)的一组扩展方法,如果可能,它们将返回基于 CNG 的实现,而不返回基于 CAPI 的实现。 (某些智能卡等仍需要 CAPI,而 API 负责管理回退过程)。System.Security.Cryptography.RSACng 类,该类提供 RSA 算法的 CNG 实现。
RSA API 的增强功能,常见操作不再需要转换。 例如,使用 X509Certificate2 对象加密数据需要早期版本的 .NET Framework 中如下所示的代码。
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey; byte[] oaepEncrypted = rsa.Encrypt(data, true); byte[] pkcs1Encrypted = rsa.Encrypt(data, false);
Dim rsa As RSACryptoServiceProvider = CType(cert.PrivateKey, RSACryptoServiceProvider) Dim oaepEncrypted() As Byte = rsa.Encrypt(data, True) Dim pkcs1Encrypted() As Byte = rsa.Encrypt(data, False)
可采用如下方式重写在 .NET Framework 4.6 中使用新加密 API 的代码以避免转换。
RSA rsa = cert.GetRSAPrivateKey(); if (rsa == null) throw new InvalidOperationException("An RSA certificate was expected"); byte[] oaepEncrypted = rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA1); byte[] pkcs1Encrypted = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
Dim rsa As RSA = cert.GetRSAPrivateKey() If rsa Is Nothing Then Throw New InvalidOperationException("An RSA certificate was expected") End If Dim oaepEncrypted() As Byte = rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA1) Dim pkcs1Encrypted() As Byte = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1)
支持将日期和时间与 Unix 时间相互转换
在 DateTimeOffset 结构中添加了以下新方法,以支持日期和时间值与 Unix 时间之间的转换:
兼容性开关
AppContext 类添加了一项新的兼容性功能,使库编写者能够为其用户提供一个统一的机制,以选择退出新的功能。 它建立组件之间的松散耦合协定,以便传达选择退出请求。 当对现有功能进行更改时,此功能通常很重要。 相反,已有新功能隐式选择加入。
通过 AppContext,库定义和公开兼容性开关,而依赖于它们的代码可以设置这些开关以影响库行为。 默认情况下,库提供新功能,并且仅在设置开关时对其进行更改(即提供以前的功能)。
应用程序(或库)可以声明依赖库定义的开关(始终是 Boolean 值)的值。 该开关始终隐式
false
。 将开关设置为true
即可启用。 将此开关显式设置为false
将提供新行为。AppContext.SetSwitch("Switch.AmazingLib.ThrowOnException", true);
AppContext.SetSwitch("Switch.AmazingLib.ThrowOnException", True)
库必须检查使用者是否已声明该开关的值,并且相应地作用于它。
if (!AppContext.TryGetSwitch("Switch.AmazingLib.ThrowOnException", out shouldThrow)) { // This is the case where the switch value was not set by the application. // The library can choose to get the value of shouldThrow by other means. // If no overrides nor default values are specified, the value should be 'false'. // A false value implies the latest behavior. } // The library can use the value of shouldThrow to throw exceptions or not. if (shouldThrow) { // old code } else { // new code }
If Not AppContext.TryGetSwitch("Switch.AmazingLib.ThrowOnException", shouldThrow) Then ' This is the case where the switch value was not set by the application. ' The library can choose to get the value of shouldThrow by other means. ' If no overrides nor default values are specified, the value should be 'false'. ' A false value implies the latest behavior. End If ' The library can use the value of shouldThrow to throw exceptions or not. If shouldThrow Then ' old code Else ' new code End If
使用一致的开关格式是有益的,因为它们是由库公开的正式协定。 以下是两种明显的格式。
Switch.namespace.switchname
Switch.library.switchname
更改为基于任务的异步模式 (TAP)
对于面向 .NET Framework 4.6、Task 和 Task<TResult> 对象的应用,请继承调用线程的区域性和 UI 区域性。 面向早期版本的 .NET Framework 或不面向特定版本的 .NET Framework 的应用的行为不受影响。 有关详细信息,请参阅 CultureInfo 类主题中的“文化和基于任务的异步操作”部分。
使用 System.Threading.AsyncLocal<T> 类可以表示给定异步控制流本地的环境数据,例如
async
方法。 它可用于跨线程保存数据。 可以定义一个回调方法,以便在环境数据发生变化时得到通知,这可能是由于 AsyncLocal<T>.Value 属性被显式更改,或者线程遇到了上下文转换。已将三种便捷方法(Task.CompletedTask、Task.FromCanceled和 Task.FromException)添加到基于任务的异步模式(TAP),以返回处于特定状态的已完成任务。
NamedPipeClientStream 类现在支持与其新的 ConnectAsync 进行异步通信。 方法。
EventSource 现在支持写入事件日志
现在,除了在计算机上创建的任何现有 ETW 会话之外,还可以使用 EventSource 类将管理或操作消息记录到事件日志。 过去,为了实现此功能,必须使用 Microsoft.Diagnostics.Tracing.EventSource NuGet 包。 此功能现已内置于 .NET Framework 4.6 中。
NuGet 包和 .NET Framework 4.6 都更新了以下功能:
动态事件
允许在不创建事件方法的情况下定义“动态”的事件。
丰富的负载
允许将专门特性化的类和数组以及基元类型作为负载传递
活动跟踪
使“开始”和“停止”事件用 ID 标记在它们之间发生的事件,以表示当前处于活动状态的所有活动。
为了支持这些功能,已将重载的 Write 方法添加到了 EventSource 类。
Windows Presentation Foundation (WPF)
HDPI 改进
WPF 中的 HDPI 支持现在在 .NET Framework 4.6 中更好。 已对布局舍入进行了更改,以减少带边框的控件中的剪切实例。 默认情况下,仅当 TargetFrameworkAttribute 设置为 .NET Framework 4.6 时,才启用此功能。 对于定位旧版 Framework,但在 .NET Framework 4.6 上运行的应用程序,可以在 app.config 文件的 <runtime> 部分中添加下面的代码行,从而选择启用新行为:
<AppContextSwitchOverrides value="Switch.MS.Internal.DoNotApplyLayoutRoundingToMarginsAndBorderThickness=false" />
跨越具有不同 DPI 设置(多 DPI 设置)的多个监视器的 WPF 窗口现在完全呈现,且没有涂黑区域。 可以通过将下面的行添加到 app.config 文件的
<appSettings>
部分来选择退出此行为,以禁用此新行为:<add key="EnableMultiMonitorDisplayClipping" value="true"/>
已将基于 DPI 设置自动加载右光标的支持添加到 System.Windows.Input.Cursor。
触摸体验更佳
在 .NET Framework 4.6 中,客户在 Connect 中报告的触控服务导致不可预测行为发生的问题得到了解决。 Windows 应用商店应用程序和 WPF 应用程序的双击阈值现在与 Windows 8.1 及更高版本中相同。
透明子窗口支持
.NET Framework 4.6 中的 WPF 支持 Windows 8.1 及更高版本中的透明子窗口。 这样,你可以在顶级窗口中创建非矩形和透明的子窗口。 可以通过将 HwndSourceParameters.UsesPerPixelTransparency 属性设置为
true
来启用此功能。
Windows Communication Foundation (WCF)
SSL 支持
WCF 现在支持 SSL 版本 TLS 1.1 和 TLS 1.2,除了 SSL 3.0 和 TLS 1.0,还支持将 NetTcp 与传输安全和客户端身份验证配合使用。 现在可以选择使用哪种协议,或者禁用旧的安全性较低的协议。 可以通过设置 SslProtocols 属性或将以下内容添加到配置文件来完成此操作。
<netTcpBinding> <binding> <security mode= "None|Transport|Message|TransportWithMessageCredential" > <transport clientCredentialType="None|Windows|Certificate" protectionLevel="None|Sign|EncryptAndSign" sslProtocols="Ssl3|Tls1|Tls11|Tls12"> </transport> </security> </binding> </netTcpBinding>
使用不同的 HTTP 连接发送消息
WCF 现在允许用户确保使用不同的基础 HTTP 连接发送某些消息。 有两种方法可以执行此操作:
使用连接组名称前缀
用户可以指定 WCF 将用作连接组名称前缀的字符串。 使用不同的基础 HTTP 连接发送两条具有不同前缀的消息。 通过将键/值对添加到消息的 Message.Properties 属性来设置前缀。 密钥为“HttpTransportConnectionGroupNamePrefix”;该值是所需的前缀。
使用不同的通道工厂
用户还可以启用一项功能,确保使用不同通道工厂创建的通道发送的消息将使用不同的基础 HTTP 连接。 若要启用此功能,用户必须将以下
appSetting
设置为true
:<appSettings> <add key="wcf:httpTransportBinding:useUniqueConnectionPoolPerFactory" value="true" /> </appSettings>
Windows Workflow Foundation (WWF)
现在可以指定当请求超时之前存在某个未完成的“非协议”书签时,工作流服务针对无序操作请求将保持的秒数。 “非协议”书签是不与未完成的“接收”活动相关的书签。 某些活动在其实现中创建非协议书签,因此可能并不明显存在非协议书签。 此类书签包括“状态”和“选取”。 因此,如果你拥有使用状态机实现的工作流服务,或包含“选取”活动的工作流服务,你将很可能具有非协议书签。 您可以通过在 app.config 文件的
appSettings
部分添加如下行来指定间隔:<add key="microsoft:WorkflowServices:FilterResumeTimeoutInSeconds" value="60"/>
默认值为 60 秒。 如果
value
设置为 0,则无序请求会被立即拒绝,并显示如下所示的错误信息:Operation 'Request3|{http://tempuri.org/}IService' on service instance with identifier '2b0667b6-09c8-4093-9d02-f6c67d534292' cannot be performed at this time. Please ensure that the operations are performed in the correct order and that the binding in use provides ordered delivery guarantees.
当收到无序操作消息且没有非协议书签时,你将收到同一条消息。
如果
FilterResumeTimeoutInSeconds
元素的值为非零,则存在非协议书签,并且超时间隔过期,操作将失败并显示超时消息。事务
你现在可以包含事务的分布式事务标识符,该事务导致了引发派生自 TransactionException 的异常。 为此,请将以下密钥添加到 app.config 文件的
appSettings
部分:<add key="Transactions:IncludeDistributedTransactionIdInExceptionMessage" value="true"/>
默认值为
false
。网络通讯
套接字重用
Windows 10 包括新的高可伸缩性网络算法,通过重用本地端口进行出站 TCP 连接,从而更好地利用计算机资源。 .NET Framework 4.6 支持新算法,使 .NET 应用能够利用新行为。 在早期版本的 Windows 中,存在人工并发连接限制(通常为 16,384,动态端口范围的默认大小),这可以通过在负载不足时导致端口耗尽来限制服务的可伸缩性。
在 .NET Framework 4.6 中,添加了两个 API 来启用端口重用,这有效地消除了并发连接的 64 KB 限制:
除非将
HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319
注册表项的HWRPortReuseOnSocketBind
值设为 0x1,否则默认情况下,ServicePointManager.ReusePort 属性为false
。 若要在 HTTP 连接上启用本地端口重用,请将 ServicePointManager.ReusePort 属性设置为true
。 这会导致来自 HttpClient 和 HttpWebRequest 的所有传出 TCP 套接字连接都会使用 Windows 10 的一个新的套接字选项(SO_REUSE_UNICASTPORT),以实现本地端口重用。编写仅使用套接字的应用程序的开发人员可以在调用 Socket.SetSocketOption 等方法时指定 System.Net.Sockets.SocketOptionName 选项,以使出站套接字在绑定期间重用本地端口。
对国际域名和 PunyCode 的支持
在 Windows 窗体控件中调整大小。
此功能已在 .NET Framework 4.6 中扩展,以包括绘制 UITypeEditor时使用的 Bounds 属性指定的 DomainUpDown、NumericUpDown、DataGridViewComboBoxColumn、DataGridViewColumn 和 ToolStripSplitButton 类型和矩形。
这是一项可选功能。 若要启用它,请将
EnableWindowsFormsHighDpiAutoResizing
元素设置为应用程序配置(app.config)文件中的true
:<appSettings> <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" /> </appSettings>
对代码页编码的支持
.NET Core 主要支持 Unicode 编码,默认情况下为代码页编码提供有限的支持。 可以使用 Encoding.RegisterProvider 方法注册代码页编码,从而支持 .NET Framework 可用但 .NET Core 不支持的代码页编码。 有关详细信息,请参阅 System.Text.CodePagesEncodingProvider。
.NET Native
使用 C# 或 Visual Basic 编写的通用 Windows 平台(UWP)应用可以利用将应用编译为本机代码而不是 IL 的新技术。 此技术可生成具有更快的启动和执行时间的应用。 有关详细信息,请参阅使用 .NET Native 编译应用。 有关 .NET Native 的概述,请参阅 .NET Native 和 Compilation,其中会检视它与 JIT 编译和 NGEN 的区别,以及这些区别对代码的影响。
使用 Visual Studio 2015 或更高版本进行编译时,默认将应用程序编译为本机代码。 有关详细信息,请参阅 .NET Native 入门。
为了支持调试 .NET Native 应用,许多新接口和枚举已添加到非托管调试 API。 有关详细信息,请参阅 调试(非托管 API 参考) 主题。
开源 .NET Framework 包
.NET Core 包(如不可变集合、SIMD API)和网络 API(如在 System.Net.Http 命名空间中找到的 API)现在可用作 GitHub上的开源包。 若要访问代码,请参阅 GitHub上的
.NET。 有关详细信息以及如何参与这些包,请参阅 .NET简介、GitHub上的 .NET 主页。
.NET Framework 4.5.2 中的新增功能
ASP.NET 应用的新 API。 新的 HttpResponse.AddOnSendingHeaders 和 HttpResponseBase.AddOnSendingHeaders 方法允许您在响应正在发送到客户端应用时检查和修改响应头和状态码。 请考虑使用这些方法,而不是 PreSendRequestHeaders 和 PreSendRequestContent 事件;它们更高效、更可靠。
使用 HostingEnvironment.QueueBackgroundWorkItem 方法可以计划小型后台工作项。 ASP.NET 跟踪这些项,并防止 IIS 在完成所有后台工作项之前突然终止工作进程。 此方法不能在 ASP.NET 托管应用域外部调用。
新的 HttpResponse.HeadersWritten 和 HttpResponseBase.HeadersWritten 属性返回指示是否已写入响应标头的布尔值。 可以使用这些属性来确保 API 的调用能够成功,例如 HttpResponse.StatusCode (如果标头已被写入,则抛出异常)。
在 Windows 窗体控件中调整大小。 此功能已扩展。 现在,您可以使用系统 DPI 设置调整以下额外控件的组件大小(例如,在组合框中的下拉箭头):
这是一项可以选择使用的功能。 若要启用它,请将
EnableWindowsFormsHighDpiAutoResizing
元素设置为应用程序配置(app.config)文件中的true
:<appSettings> <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" /> </appSettings>
新的工作流功能。 使用 EnlistPromotableSinglePhase 方法(因此实现 IPromotableSinglePhaseNotification 接口)的资源管理器可以使用新的 Transaction.PromoteAndEnlistDurable 方法请求以下内容:
将该事物提升为 Microsoft 分布式事务处理协调器 (MSDTC) 事物。
使用 IPromotableSinglePhaseNotification 替换 ISinglePhaseNotification,它是支持单阶段提交的持久性登记。
此操作可以在相同的应用域内执行,而且不需要任何用于与 MSDTC 交互的额外非托管代码即可执行提升。 仅当存在从 System.Transactions 对由可提升登记实现的 IPromotableSinglePhaseNotification
Promote
方法进行的未处理调用时,才可调用新方法。分析改进。 以下新的非托管分析 API 提供更可靠的分析:
- COR_PRF_ASSEMBLY_REFERENCE_INFO 结构
- COR_PRF_HIGH_MONITOR 枚举
- GetAssemblyReferences 方法
- GetEventMask2 方法
- SetEventMask2 方法
- AddAssemblyReference 方法
之前的
ICorProfiler
实现支持依赖程序集的延迟加载。 新的分析 API 要求探查器注入的依赖程序集可以立即加载,而不是在完全初始化应用后加载。 此更改不会影响现有ICorProfiler
API 的用户。调试改进。 以下新的非托管调试 API 提供与探查器更好的集成。 你现在可以访问由探查器插入的元数据,以及转储调试时编译器 ReJIT 请求所生成的本地变量和代码。
事件跟踪更改。 .NET Framework 4.5.2 为较大的表面区域启用进程外的基于 Windows 事件跟踪 (ETW) 的活动跟踪。 这使高级电源管理(APM)供应商能够提供轻量级工具,以准确跟踪跨线程的各个请求和活动的成本。 只有当 ETW 控制器启用这些事件时,才会引发这些事件;因此,更改不会影响以前编写的 ETW 代码或在禁用 ETW 时运行的代码。
提升事务并将其转换为持久登记
Transaction.PromoteAndEnlistDurable 是添加到 .NET Framework 4.5.2 和 4.6 的新 API:
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")] public Enlistment PromoteAndEnlistDurable(Guid resourceManagerIdentifier, IPromotableSinglePhaseNotification promotableNotification, ISinglePhaseNotification enlistmentNotification, EnlistmentOptions enlistmentOptions)
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name:="FullTrust")> public Function PromoteAndEnlistDurable(resourceManagerIdentifier As Guid, promotableNotification As IPromotableSinglePhaseNotification, enlistmentNotification As ISinglePhaseNotification, enlistmentOptions As EnlistmentOptions) As Enlistment
该方法可能会由登记使用,该登记先前通过 Transaction.EnlistPromotableSinglePhase 创建以响应 ITransactionPromoter.Promote 方法。 它要求
System.Transactions
将事务提升为 MSDTC 事务,并将可提升的登记“转换”为持久登记。 此方法成功完成后,IPromotableSinglePhaseNotification 接口将不再由System.Transactions
引用,将来的任何通知都将到达提供的 ISinglePhaseNotification 接口。 相关登记必须作为持久登记,以支持事务日志记录和恢复。 有关详细信息,请参阅 Transaction.EnlistDurable。 此外,登记必须支持 ISinglePhaseNotification。 此方法只能在处理 ITransactionPromoter.Promote 调用时调用。 如果不是这种情况,则会引发 TransactionException 异常。
.NET Framework 4.5.1 中的新增功能
2014 年 4 月版更新:
Visual Studio 2013 Update 2 中,可移植类库模板已更新以支持这些方案:
可以在面向 Windows 8.1、Windows Phone 8.1 和 Windows Phone Silverlight 8.1 的可移植库中使用 Windows 运行时 API。
在面向 Windows 8.1 或 Windows Phone 8.1 时,你可以在可移植库中包含 XAML(Windows.UI.XAML 类型)。 支持以下 XAML 模板:空白页、资源字典、模板化控件和用户控件。
可以创建可移植的 Windows 运行时组件(.winmd 文件),以便在面向 Windows 8.1 和 Windows Phone 8.1 的应用商店应用中使用。
你可以重定 Windows 应用商店或 Windows Phone 应用商店类库(例如可移植类库)的目标。
有关这些更改的详细信息,请参阅 可移植类库。
.NET Framework 内容集现在包含适用于 .NET Native 的文档,这是用于生成和部署 Windows 应用的预编译技术。 .NET Native 将应用直接编译为本机代码,而不是中间语言(IL),以提高性能。 有关详细信息,请参阅使用 .NET Native 编译应用。
.NET Framework 参考源 提供了新的浏览体验和增强功能。 现在可以联机浏览 .NET Framework 源代码,下载引用以供脱机查看,并在调试时逐步执行源(包括修补程序和更新)。 有关详细信息,请参阅博客文章 .NET 参考源的新界面。
.NET Framework 4.5.1 基类中的新功能和增强功能包括:
程序集的自动绑定重定向。 从 Visual Studio 2013 开始,当你编译面向 .NET Framework 4.5.1 的应用时,如果应用或其组件引用同一程序集的多个版本,则可以将绑定重定向添加到应用配置文件。 还可以为面向旧版 .NET Framework 的项目启用此功能。 有关详细信息,请参阅如何:启用和禁用自动绑定重定向。
能够收集诊断信息,帮助开发人员提高服务器和云应用程序的性能。 有关详细信息,请参阅 EventSource 类中的 WriteEventWithRelatedActivityId 和 WriteEventWithRelatedActivityIdCore 方法。
可以在垃圾回收过程中显式压缩大对象堆 (LOH)。 有关详细信息,请参阅 GCSettings.LargeObjectHeapCompactionMode 属性。
其他性能改进,例如 ASP.NET 应用挂起、多核 JIT 改进,以及更新 .NET Framework 后更快的应用启动。 有关详细信息,请参阅 .NET Framework 4.5.1 公告和 ASP.NET 应用挂起博客文章。
Windows 窗体的改进包括:
在 Windows 窗体控件中调整大小。 您可以通过在应用程序配置文件(app.config)中添加条目来启用系统 DPI 设置,从而调整控件组件(例如属性网格中显示的图标)的大小。 以下 Windows 窗体控件当前支持此功能:
- PropertyGrid
- TreeView
- DataGridView 的某些方面(有关支持的其他控件,请参阅 4.5.2 中的新功能)
若要启用此功能,请将新的 <appSettings> 元素添加到配置文件(app.config),并将
EnableWindowsFormsHighDpiAutoResizing
元素设置为true
:<appSettings> <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" /> </appSettings>
在 Visual Studio 2013 中调试 .NET Framework 应用时的改进包括:
返回 Visual Studio 调试器中的值。 在 Visual Studio 2013 中调试托管应用时,“自动”窗口显示方法的返回类型和值。 此信息适用于桌面、Windows 应用商店和 Windows Phone 应用。 有关详细信息,请参阅 检查方法调用的返回值。
针对 64 位应用程序的“编辑并继续”。 Visual Studio 2013 支持适用于桌面、Windows 应用商店和 Windows Phone 的 64 位托管应用的“编辑并继续”功能。 对于 32 位和 64 位应用,现有限制仍然有效(请参阅 支持的代码更改(C#) 文章的最后一部分)。
异步识别调试。 为了更轻松地在 Visual Studio 2013 中调试异步应用,调用堆栈隐藏编译器提供的基础结构代码以支持异步编程,并链接在逻辑父帧中,以便可以更清楚地遵循逻辑程序执行。 “任务”窗口替换“并行任务”窗口,并显示与特定断点相关的任务,并显示应用中当前处于活动状态或计划的任何其他任务。 可以在 .NET Framework 4.5.1 公告的“异步感知调试”部分中阅读此功能。
更好地支持 Windows 运行时组件中的异常处理。 在 Windows 8.1 中,Windows 应用商店应用产生的异常会保留导致异常的错误的相关信息,甚至跨越语言边界。 可以在 .NET Framework 4.5.1 公告的“Windows 应用商店应用开发”部分中阅读此功能。
从 Visual Studio 2013 开始,可以使用 托管配置文件引导式优化工具(Mpgo.exe) 来优化 Windows 8.x 应用商店应用以及桌面应用。
有关 ASP.NET 4.5.1 中的新功能,请参阅适用于 Visual Studio 2013 的 ASP.NET 和 Web 工具发行说明.
.NET Framework 4.5 中的新增功能
基类
通过在部署期间检测和关闭 .NET Framework 4 应用程序来减少系统重启的能力。 请参阅在 .NET Framework 4.5 安装期间减少系统重新启动。
支持 64 位平台上大于 2 GB 的数组。 可以在应用程序配置文件中启用此功能。 请参阅 <gcAllowVeryLargeObjects> 元素,其中还列出了对象大小和数组大小的其他限制。
通过服务器后台垃圾回收提高性能。 在 .NET Framework 4.5 中使用服务器垃圾回收时,会自动启用后台垃圾回收。 请参阅垃圾回收基础知识主题中有关后台服务器垃圾回收的部分。
后台实时 (JIT) 编译(可选)可用于多核处理器,以提高应用程序性能。 请参阅 ProfileOptimization。
能够限制正则表达式引擎在超时前尝试解析正则表达式的最长时间。请参阅 Regex.MatchTimeout 属性。
能够设置应用程序域的默认文化环境。 请参阅 CultureInfo 类。
Unicode (UTF-16) 编码的控制台支持。 请参阅 Console 类。
支持对区域性字符串排序和比较数据进行版本控制。 请参阅 SortVersion 类。
检索资源时性能更佳。 请参阅打包和部署资源。
Zip 压缩改进旨在减少文件的压缩大小。 请参阅 System.IO.Compression 命名空间。
能够自定义反射上下文,以通过 CustomReflectionContext 类替代默认反射行为。
在 Windows 8 上使用 System.Globalization.IdnMapping 类时支持应用程序国际化域名 (IDNA) 标准的 2008 版。
在 Windows 8 上使用 .NET Framework 时,将字符串比较的任务委派给实现 Unicode 6.0 的操作系统。 在其他平台上运行时,.NET Framework 包含其自己的字符串比较数据,该数据实现 Unicode 5.x。 请参阅 String 类和 SortVersion 类的“备注”部分。
能够基于每个应用程序域计算字符串的哈希代码。 请参阅 <UseRandomizedStringHashAlgorithm> 元素。
类型反射支持 Type 和 TypeInfo 类之间的拆分。 请参阅 .NET Framework 中用于 Windows 应用商店应用的反射。
Managed Extensibility Framework (MEF)
在 .NET Framework 4.5 中,托管扩展性框架(MEF)提供以下新功能:
支持泛型类型。
基于约定的编程模型,使你能够基于命名约定而不是属性创建部件。
多个范围。
创建 Windows 8.x 应用商店应用时可以使用的 MEF 子集。 此子集可作为 NuGet 库中的可下载程序包提供。 若要安装包,请在 Visual Studio 中打开项目,从“项目”菜单中选择“管理 NuGet 包”,然后联机搜索
Microsoft.Composition
包。
有关详细信息,请参阅 托管扩展性框架(MEF)。
异步文件操作
在 .NET Framework 4.5 中,向 C# 和 Visual Basic 语言添加了新的异步功能。 这些功能添加用于执行异步操作的基于任务的模型。 若要使用此新模型,请使用 I/O 类中的异步方法。 请参阅 异步文件输入/输出。
工具
在 .NET Framework 4.5 中,资源文件生成器(Resgen.exe)使你可以创建一个 .resw 文件,以便从嵌入在 .NET Framework 程序集中的 .resources 文件在 Windows 8.x 应用商店应用中使用。 有关详细信息,请参阅 Resgen.exe(资源文件生成器)。
利用按托管配置优化 (Mpgo.exe) 工具,你可以通过优化本机映像程序集来改进应用程序的启动时间、内存使用率(工作集大小)和吞吐量。 命令行工具为本地映像应用程序程序集生成概要数据。 请参阅 Mpgo.exe(按托管配置文件优化工具)。 从 Visual Studio 2013 开始,可以使用 Mpgo.exe 来优化 Windows 8.x 应用商店应用以及桌面应用。
并行计算
.NET Framework 4.5 为并行计算提供了多项新功能和改进。 其中包括改进的性能、提高的控制、改进对异步编程的支持、新的数据流库,以及改进对并行调试和性能分析的支持。 请参阅 .NET 编程博客中关于并行编程的文章 《.NET Framework 4.5 中并行的新增功能》。
网络
ASP.NET 4.5 和 4.5.1 为 Web 窗体、WebSocket 支持、异步处理程序、性能增强和其他许多功能添加模型绑定。 有关详细信息,请参阅以下资源:
网络
.NET Framework 4.5 为 HTTP 应用程序提供了新的编程接口。 有关详细信息,请参阅新的 System.Net.Http 和 System.Net.Http.Headers 命名空间。
还包含针对用于接受 WebSocket 连接并与之交互(通过使用现有 HttpListener 和相关类)的新编程接口的支持。 有关详细信息,请参阅新的 System.Net.WebSockets 命名空间和 HttpListener 类。
此外,.NET Framework 4.5 还包括以下网络改进:
RFC 兼容的 URI 支持。 有关详细信息,请参阅 Uri 和相关类。
支持国际化域名(IDN)解析。 有关详细信息,请参阅 Uri 和相关类别。
支持电子邮件地址国际化(EAI)。 有关详细信息,请参阅 System.Net.Mail 命名空间。
改进了 IPv6 支持。 有关详细信息,请参阅 System.Net.NetworkInformation 命名空间。
双重模式套接字支持。 有关详细信息,请参阅 Socket 和 TcpListener 类。
Windows Presentation Foundation (WPF)
在 .NET Framework 4.5 中,Windows Presentation Foundation(WPF)包含以下方面的更改和改进:
新的 Ribbon 控件,可用于实现托管快速访问工具栏、应用程序菜单和选项卡的功能区用户界面。
新的 INotifyDataErrorInfo 接口,支持同步和异步数据验证。
VirtualizingPanel 和 Dispatcher 类的新功能。
通过在非 UI 线程上访问集合,改进了在显示大型分组数据集时的性能。
将数据绑定到静态属性、将数据绑定到实现 ICustomTypeProvider 接口的自定义类型,以及从绑定表达式检索数据绑定信息。
当数值变化时对数据进行重新定位(实时调整)。
能够检查项目容器的数据上下文是否已断开连接。
能够设置属性更改和数据源更新之间应经过的时间量。
改进了对实现弱事件模式的支持。 此外,事件现在可以接受标记扩展。
Windows Communication Foundation (WCF)
在 .NET Framework 4.5 中,添加了以下功能,以便更轻松地编写和维护 Windows Communication Foundation (WCF) 应用程序:
简化生成的配置文件。
支持合同优先开发。
能够更轻松地配置 ASP.NET 兼容性模式。
为了减少您需要设置默认传输属性值的可能性,我们对其进行了更改。
对 XmlDictionaryReaderQuotas 类的更新,以减少必须手动为 XML 字典读取器配置配额的可能性。
在生成过程中,Visual Studio 验证 WCF 配置文件,以便在运行应用程序之前检测配置错误。
新增异步流媒体支持。
新的 HTTPS 协议映射,使你能够更轻松地通过 Internet Information Services (IIS) 在 HTTPS 上公开终结点。
通过将
?singleWSDL
追加到服务 URL,能够在单个 WSDL 文档中生成元数据。Websocket 支持通过端口 80 和 443 实现真正的双向通信,其性能特征类似于 TCP 传输。
支持在代码中配置服务。
XML 编辑器工具提示。
ChannelFactory 缓存支持。
二进制编码器压缩支持。
对 UDP 传输的支持,这可使开发人员编写使用“发后不理”消息的服务。 客户端向服务发送消息,并不期待服务的响应。
使用 HTTP 传输和传输安全性时,能够在单个 WCF 终结点上支持多种身份验证模式。
对使用国际域名 (IDN) 的 WCF 服务的支持。
有关详细信息,请参阅 Windows Communication Foundation中的新增功能。
Windows Workflow Foundation (WF)
在 .NET Framework 4.5 中,Windows Workflow Foundation(WF)添加了几个新功能,包括:
状态机工作流首次作为 .NET Framework 4.0.1 的一部分引入(.NET Framework 4 平台更新 1)。 此更新包含多个新类和活动,使开发人员能够创建状态机工作流。 这些类和活动已更新为 .NET Framework 4.5,包括:
对状态设置断点的功能。
在工作流设计器中复制和粘贴转换的功能。
对共享的触发器转换创建的设计器支持。
用于创建状态机工作流的活动,包括:StateMachine、State和 Transition。
增强的工作流设计器功能,如下所示:
Visual Studio 中增强的工作流搜索功能,包括“快速查找”和“在文件中查找”。
能够在向容器活动添加第二个子活动时自动创建序列活动,并将这两个活动包括在该序列活动中。
平移支持,使工作流的可见部分无需使用滚动条即可更改。
新的 文档大纲 视图,显示树样式大纲视图中工作流的组件,并允许在 文档大纲 视图中选择组件。
向活动中添加批注的能力。
通过使用工作流设计器定义和使用活动委托的能力。
状态机和流程图工作流中活动和转换的自动连接和自动插入。
在 XAML 文件中的单个元素中存储工作流的视图状态信息,以便可以轻松查找和编辑视图状态信息。
可防止子活动持久化的 NoPersistScope 容器活动。
支持 C# 表达式:
使用 Visual Basic 的工作流项目将使用 Visual Basic 表达式,C# 工作流项目将使用 C# 表达式。
在 Visual Studio 2010 中创建且具有 Visual Basic 表达式的 C# 工作流项目与使用 C# 表达式的 C# 工作流项目兼容。
版本控制增强功能:
新的 WorkflowIdentity 类,该类提供持久化工作流实例与其工作流定义之间的映射。
在同一主机中并行执行多个工作流版本,包括 WorkflowServiceHost。
在动态更新中,能够修改持久化工作流实例的定义。
契约优先工作流服务开发,支持自动生成活动以匹配现有服务合同。
有关详细信息,请参阅 Windows Workflow Foundation中的新增功能。
适用于 Windows 8.x 应用商店应用的 .NET
Windows 8.x 应用商店应用专为特定外形规格设计,并利用 Windows 操作系统的强大功能。 .NET Framework 4.5 或 4.5.1 的子集可用于使用 C# 或 Visual Basic 生成适用于 Windows 的 Windows 8.x 应用商店应用。 此子集称为适用于 Windows 8.x 应用商店应用的 .NET,并在 概述中讨论。
可移植类库
Visual Studio 2012(及更高版本)中的可移植类库项目可用于编写和生成在多个 .NET Framework 平台上工作的托管程序集。 使用可移植类库项目,您可以选择要面向的平台,例如 Windows Phone 和用于 Windows 8.x 商店应用的 .NET。 项目中的可用类型和成员会自动限制为这些平台上的常见类型和成员。 有关详细信息,请参阅 可移植类库。