.NET Framework 中的新增功能

注意

.NET Framework 4.8 是 .NET Framework 的上一个版本。 .NET Framework 每月提供一次安全性和可靠性 bug 修补程序。 .NET Framework 将继续包含在 Windows 中,我们没有删除它的计划。 无需迁移 .NET Framework 应用,但如果要进行新的开发,请使用 .NET 5 或更高版本

本文总结了以下版本的 .NET Framework 中的主要新功能和改进:

本文不提供有关每项新增功能的完整信息,并有可能会发生更改。 有关 .NET Framework 的常规信息,请参阅入门。 有关支持的平台,请参阅系统要求。 有关下载链接和安装说明,请参阅安装指南

注意

.NET Framework 团队还发布 NuGet 带外功能以扩展平台支持并引入新功能,如不可变集合和启用了 SIMD 的矢量类型。 有关详细信息,请参阅其他类库和 API 以及 .NET Framework 和带外版本。 请参阅用于 .NET Framework 的 完整 NuGet 包列表

.NET Framework 4.8 简介

.NET Framework 4.8 在 .NET Framework 4.x 早期版本的基础之上构建而成,新增了许多修补程序和功能,同时很好地保持了产品的稳定性。

下载和安装 .NET Framework 4.8

可以从下列位置下载 .NET Framework 4.8:

可以在 Windows 10、Windows 8.1、Windows 7 SP1 和对应的服务器平台(版本不低于 Windows Server 2008 R2 SP1)上安装 .NET Framework 4.8。 可以使用 Web 安装程序或脱机安装程序来安装 .NET Framework 4.8。 适用于大多数用户的建议方法是使用 Web 安装程序。

可以通过安装 .NET Framework 4.8 开发人员工具包,在 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 中辅助功能的新增功能

基类

减少 FIPS 对加密的影响。 在 .NET framework 的早期版本中,当在“FIPS 模式”下配置系统加密库时,SHA256Managed 等托管加密提供程序类会引发 CryptographicException。 引发这些异常的原因是加密提供程序类的托管版本尚未进行 FIPS(联邦信息处理标准)140-2 认证,这与系统加密库不同。 由于几个开发人员使其开发计算机处于 FIPS 模式,因此通常会在生产系统中引发异常。

默认情况下,在面向 .NET Framework 4.8 的应用程序中,以下托管加密类在这种情况下不再引发 CryptographicException

相反,这些类会将加密操作重定向到系统加密库。 此更改可有效地删除开发人员环境和生产环境之间可能令人混淆的差异,并使本机组件和托管组件采用相同的加密策略运行。 依赖于这些异常的应用程序可以通过将 AppContext 开关 Switch.System.Security.Cryptography.UseLegacyFipsThrow 设置为 true 来还原以前的行为。 有关详细信息,请参阅托管加密类不会在 FIPS 模式下引发 CryptographyException

使用 ZLib 的更新版本

从 .NET Framework 4.5 开始,clrcompression.dll 程序集使用 ZLib(即,数据压缩的本机外部库),以便提供 deflate 算法实现。 在 .NET Framework 4.8 版本中,clrcompression.dll 更新为使用 ZLib 版本 1.2.11,其中包括几个主要的改进和修补程序。

Windows Communication Foundation (WCF)

ServiceHealthBehavior 简介

运行状况终结点由业务流程工具广泛使用以基于其运行状况状态来管理服务。 运行状况检查还可由监视工具使用以跟踪并提供有关服务的可用性和性能的通知。

ServiceHealthBehavior 是一个 WCF 服务行为,该行为可扩展 IServiceBehavior。 添加到 ServiceDescription.Behaviors 集合后,服务行为会执行以下操作:

  • 返回带有 HTTP 响应代码的服务运行状况状态。 可以在查询字符串中指定 HTTP/GET 运行状况探测请求的 HTTP 状态代码。

  • 发布有关服务运行状况的信息。 服务特定的详细信息,包括可以使用带有 ?health 查询字符串的 HTTP/GET 请求显示的服务状态、限制计数和容量。 对行为不正常的 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>
    

可以使用查询参数(例如,OnServiceFailureOnDispatcherFailureOnListenerFailureOnThrottlePercentExceeded)查询服务的运行状况状态,并且可以为每个查询参数指定 HTTP 响应代码。 如果省略了查询参数的 HTTP 响应代码,则默认使用 503 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

    指定触发响应及其 HTTP 响应代码 {200 – 599} 的百分比 {1 – 100}。 在此示例中:

    • 如果百分比大于 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 添加了对按监视器 V2 DPI 感知和混合模式 DPI 缩放的支持。 有关高 DPI 开发的其他信息,请参阅在 Windows 上开发高 DPI 桌面应用程序

.NET framework 4.8 改进了对支持混合模式 DPI 缩放的平台上的高 DPI WPF 应用程序中的寄宿 HWND 和 Windows 窗体互操作的支持(从 Windows 10 2018 年 4 月更新开始)。 通过调用 SetThreadDpiHostingBehaviorSetThreadDpiAwarenessContext 将寄宿 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 Core 2.1 JIT 编译器所做的多个优化和所有 bug 修复都包含在 .NET Framework 4.8 JIT 编译器中。

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) 方法,可以在实例化新的 DSARSA 密钥时提供密钥参数。 它们允许你替换如下所示的代码:

// 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) 方法允许生成具有特定密钥大小的 DSARSA 密钥。 例如:

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-1 相比,开发人员应使用基于 SHA-2 的 HMAC,例如 SHA-256,如下面的示例所示:

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 加载的。 因此,调用方必须通过调用扩展方法访问私钥,例如 cert.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 将一些新 API 添加到 SortedSet<T>HashSet<T> 类型。 这些方法包括:

ConcurrentDictionary<TKey,TValue> 类包含 AddOrUpdateGetOrAdd 方法的新重载,以便在词典中检索值或添加找不到的值,以及将值添加到词典或者更新已存在的值。

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 添加了一个值为 System.Web.SameSiteMode 枚举成员的 HttpCookie.SameSite 属性。 如果它的值为 SameSiteMode.StrictSameSiteMode.Lax,ASP.NET 将 SameSite 属性添加到 set-cookie 标头。 SameSite 支持适用于 HttpCookie 对象,以及 FormsAuthenticationSystem.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 配置文件,可以为 FormsAuthenticationSystem.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.ActiveDirectoryPasswordSqlAuthenticationMethod.ActiveDirectoryIntegrated 选项。 两者都是非交互式 ADAL 协议的一部分,而该协议不支持 MFA。 利用新的 SqlAuthenticationMethod.ActiveDirectoryInteractive 选项,SQL 连接可支持 MFA 以及现有身份验证方法(密码和集成身份验证),让用户可以交互式地输入用户密码,而无需将密码存留在连接字符串中。

有关详细信息和示例,请参阅 .NET 博客中的“SQL - Azure AD 通用和多重身份验证支持”。

Always Encrypted 版本 2 的支持

NET Framework 4.7.2 为基于 enclave 的 Always Encrypted 添加支持。 Always Encrypted 的原始版本是客户端加密技术,其中的加密密钥不会离开客户端。 在基于 enclave 的 Always Encrypted 中,客户端可以选择将加密密钥发送到安全的 enclave,即一个安全的计算实体,该实体可以看作是 SQL Server 的一部分,但 SQL Server 代码无法对其进行篡改。 为了支持基于 enclave 的 Always Encrypted,NET Framework 4.7.2 将以下类型和成员添加到 System.Data.SqlClient 命名空间:

抽象 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 的基本流是:

  1. 用户创建与 SQL Server(支持基于 enclave 的 Always Encrypted)的 AlwaysEncrypted 连接。 驱动程序联系认证服务以确保它连接到正确的 enclave。

  2. enclave 验证成功后,驱动程序将建立与托管在 SQL Server 上的安全 enclave 之间的安全信道。

  3. 在 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)

每当运行时解析 StaticResource 引用时,都会引发此事件。 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 必须可用于支持 Standard 版本的每个 .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 中也延续使用。 (请注意,这些版本的 .NET Framework 只有在其他 .NET Standard 支持文件也部署在目标系统时才支持 .NET Standard 2.0。)有关详细信息,请参阅 .NET Framework 4.7.1 Runtime and Compiler Features(.NET Framework 4.7.1 运行时和编译器功能)博客文章中的“BCL - .NET Standard 2.0 Support”(BCL - .NET Standard 2.0 支持)。

支持配置生成器

配置生成器允许开发者在运行时动态地插入和生成应用程序的配置设置。 自定义配置生成器可用于修改配置节中的现有数据,也可用于生成全新的配置节。 如果没有配置生成器,.config 文件将是静态的,并且其设置将在应用程序启动之前定义。

若要创建自定义配置生成器,请从抽象的 ConfigurationBuilder 类派生生成器并且替代其 ConfigurationBuilder.ProcessConfigurationSectionConfigurationBuilder.ProcessRawXml。 也可在 .config 文件中定义生成器。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET and Configuration Features(.NET Framework 4.7.1 ASP.NET 和配置功能)博客文章中的“Configuration Builders”(配置生成器)一节。

运行时功能检测

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 Runtime and Compiler Features(.NET Framework 4.7.1 运行时和编译器功能)博客文章中的“Compiler -- ValueTuple is Serializable”(编译器 -- 值元组是可序列化的)。

支持只读引用

.NET Framework 4.7.1 增加了 System.Runtime.CompilerServices.IsReadOnlyAttribute。 此特性由语言编译器用于标记具有只读 ref 返回类型或参数的成员。 有关详细信息,请参阅 .NET Framework 4.7.1 Runtime and Compiler Features(.NET Framework 4.7.1 运行时和编译器功能)博客文章中的“Compiler -- Support for ReadOnlyReferences”(编译器 -- 支持只读引用)。 有关 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 Runtime and Compiler Features(.NET Framework 4.7.1 运行时和编译器功能)博客文章中的“Runtime -- GC Performance Improvements”(运行时 -- GC 性能改进)一节。

网络

Message.HashAlgorithm 的 SHA-2 支持

在 .NET Framework 4.7 及早期版本中,Message.HashAlgorithm 属性仅支持 HashAlgorithm.Md5HashAlgorithm.Sha 的值。 从 .NET Framework 4.7.1 开始,还支持 HashAlgorithm.Sha256HashAlgorithm.Sha384HashAlgorithm.Sha512。 实际是否使用此值取决于消息队列,因为 Message 实例本身不进行哈希处理,而是简单地将值传递到消息队列。 有关详细信息,请参阅 .NET Framework 4.7.1 ASP.NET and Configuration Features(.NET Framework 4.7.1 ASP.NET 和配置功能)博客文章中的“SHA-2 support for Message.HashAlgorithm”(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 and Configuration Features(.NET Framework 4.7.1 ASP.NET 和配置功能)博客文章的“ASP.NET Execution Step Feature”(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 配置文件中定义。 例如:

<system.web>
    <authentication mode="Forms">
        <forms loginUrl="~/login.aspx">
          <credentials passwordFormat="SHA512">
            <user name="jdoe" password="6D003E98EA1C7F04ABF8FCB375388907B7F3EE06F278DB966BE960E7CBBD103DF30CA6D61F7E7FD981B2E4E3A64D43C836A4BEDCA165C33B163E6BCDC538A664" />
          </credentials>
        </forms>
    </authentication>
</system.web>

.NET Framework 4.7 中的新增功能

.NET Framework 4.7 在以下几个领域新增了功能:

有关 .NET Framework 4.7 中新增 API 的列表,请参阅 GitHub 上的 .NET Framework 4.7 API 更改。 有关 .NET Framework 4.7 中功能改进和 bug 修复的列表,请参阅 GitHub 上的 .NET Framework 4.7 更改列表。 有关详细信息,请参阅 .NET 博客中的 Announcing the .NET Framework 4.7(发布 .NET Framework 4.7)。

基类

.NET Framework 4.7 通过 DataContractJsonSerializer 改进了序列化:

借助椭圆曲线加密 (ECC) 增强了功能*

在 .NET Framework 4.7 中,ImportParameters(ECParameters) 方法已添加到 ECDsaECDiffieHellman 类,以允许对象表示已经建立的密钥。 此外,还添加了 ExportParameters(Boolean) 方法,以便于使用显式曲线参数导出密钥。

.NET Framework 4.7 现已开始支持其他曲线(其中包括 Brainpool 曲线套件),并添加了预定义的定义,以便于通过新工厂方法 CreateCreate 简化创建操作。

有关 .NET Framework 4.7 加密改进示例,请访问 GitHub。

通过 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 中的默认内存监视器就会通知应用程序。 接近这些限制时,就会触发通知。 对于某些应用程序,通知的触发点与限制过近,无法及时响应。 开发人员现在可以编写自己的内存监视器,以通过使用 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 起,除了 SSL 3.0 和 TLS 1.0 外,WCF 还允许配置 TLS 1.1 或 TLS 1.2 作为默认消息安全协议。 这是一项选择启用设置;必须向应用程序配置文件添加以下条目,才能启用此设置:

<runtime>
   <AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>

提升了 WCF 应用程序和 WCF 序列化的可靠性

WCF 包含大量代码更改,消除了争用条件,从而提升了序列化选项的性能和可靠性。 其中包括:

  • 更好地支持在调用 SocketConnection.BeginReadSocketConnection.Read 时混合异步和同步代码。
  • 提升了在中止与 SharedConnectionListenerDuplexChannelBinder 的连接时的可靠性。
  • 提高了调用 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 窗体中的高 DPI 支持

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 博客中的 Announcing the .NET Framework 4.6.2(发布 .NET Framework 4.6.2)。

ASP.NET

在 .NET Framework 4.6.2 中,ASP.NET 包括以下增强功能:

改进了对数据注释验证程序中本地化错误消息的支持

数据批注验证程序使你能够通过将一个或多个属性添加到类属性来执行验证。 如果验证失败,该属性的 ValidationAttribute.ErrorMessage 元素定义错误消息的文本。 自 .NET Framework 4.6.2 起,ASP.NET 简化了错误消息的本地化。 如果有以下情况,将本地化错误消息:

  1. 验证属性中提供 ValidationAttribute.ErrorMessage

  2. 资源文件存储在 App_LocalResources 文件夹中。

  3. 本地化资源文件名称的格式为 DataAnnotation.Localization.{name}.resx,其中 name 是采用 languageCode-country/regionCodelanguageCode 格式的区域性名称。

  4. 该资源的项名称是分配给 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.Localization.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 类包括两种新方法:IsSessionStateReadOnlyIsSessionStateRequired,可用来支持异步操作。

对输出缓存提供程序的异步支持

自 .NET Framework 4.6.2 起,返回任务的方法可与输出缓存提供程序结合使用,从而实现异步的可伸缩性优势。 实现这些方法的提供程序减少了 Web 服务器上的线程阻止,并提高 ASP.NET 服务的可伸缩性。

添加了以下 API 以支持异步输出缓存提供程序:

字符类别

.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 Consortium 网站上的 Unicode 标准 7.0.0 版。 有关从 Unicode 7.0 到 Unicode 8.0 的更改,请参阅 Unicode Consortium 网站上的 Unicode 标准 8.0.0 版

密码

对包含 FIPS 186-3 DSA 的 X509 证书的支持

.NET Framework 4.6.2 现已开始支持密钥超过 FIPS 186-2 1024 位限制的 DSA(数字签名算法)X509 证书。

除了支持更大的 FIPS 186-3 密钥大小之外,.NET Framework 4.6.2 还支持使用 SHA-2 系列的哈希算法(SHA256、SHA384 和 SHA512)计算签名。 FIPS 186-3 支持由新的 System.Security.Cryptography.DSACng 类提供。

为了跟进 .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 通过三个不同的密钥派生功能 (KDF) 例程增加了对椭圆曲线 Diffie-Hellman 密钥协议的支持。 例程的输入以及这些例程本身通过 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 中的 SignedXml 类现已开始支持 RSA-SHA256、RSA-SHA384 和 RSA-SHA512 PKCS#1 签名方法,还支持 SHA256、SHA384 和 SHA512 引用摘要算法。

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 关键字的添加使你能够选择最适合你的应用的阻塞期。 值包括:

Auto

已禁用连接到 Azure SQL 数据库的应用程序的连接池阻塞期,已启用连接到任何其他 SQL Server 实例的应用程序的连接池阻塞期。 这是默认值。 如果 Server 终结点名称采用以下任一结尾,则将它们视为 Azure SQL 数据库:

  • .database.windows.net

  • .database.chinacloudapi.cn

  • .database.usgovcloudapi.net

  • .database.cloudapi.de

AlwaysBlock

连接池阻塞期始终处于启用状态。

NeverBlock

连接池阻塞期始终处于禁用状态。

Always Encrypted 的增强功能

SQLClient 引入了针对 Always Encrypted 的两个增强功能:

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 文件的 <runtime> 部分中添加以下代码行来启用此功能。

<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 不再是用于协商安全连接的默认协议。 在大多数情况下,应该不会影响现有应用,因为 TLS 1.0 包含在 NetTcp 的协议列表中。 所有现有客户端应该能够至少使用 TLS 1.0 协商连接。 如果 Ssl3 必需,则使用以下配置机制之一将其添加到协商协议的列表。

Windows Presentation Foundation (WPF)

在 .NET Framework 4.6.2 中,Windows Presentation Foundation 在以下几个方面进行了增强:

组排序

使用 CollectionView 对象对数据进行分组的应用程序现在可以显式声明如何对组进行排序。 显式排序可解决在应用动态添加或删除组,或在它更改分组中包含的项属性的值时出现的非直观排序问题。 它还可通过将分组属性比较从完整集合排序移动到组排序来改善组创建过程的性能。

为支持组排序,新的 GroupDescription.SortDescriptionsGroupDescription.CustomSort 属性描述如何对 GroupDescription 对象生成的组的集合进行排序。 这类似于同名 ListCollectionView 属性描述如何对数据项进行排序的方式。

PropertyGroupDescription 类的两个新静态属性:CompareNameAscendingCompareNameDescending,可用于最常见的情况。

例如,下面的 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 控制下运行的应用程序,可以在应用程序配置文件的 <runtime> 部分中添加配置语句,在 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 设计器和代码工作流中使用 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 设计器 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 中为调用 DynamicUpdateServices.PrepareForUpdate 后保存的工作流加载 XAML 文件可能会导致以下问题:

  • 工作流设计器无法正确加载 XAML 文件(当 ViewStateData.Id 位于行末尾处时)。

  • 流程图活动设计器或其他工作流活动设计器可能在其默认位置显示所有对象,与附加的属性值相反。

ClickOnce

除现已支持的 1.0 协议以外,ClickOnce 已更新为还支持 TLS 1.1 和 TLS 1.2。 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。

.NET Framework 4.6.1 中的新增功能

.NET Framework 4.6.1 在以下几个领域新增了功能:

若要详细了解 .NET Framework 4.6.1,请参阅以下主题:

加密:支持包含 ECDSA 在内的 X509 证书

.NET Framework 4.6 添加了针对 X509 证书的 RSACng 支持。 .NET Framework 4.6.1 现已开始支持 ECDSA(椭圆曲线数字签名算法)X509 证书。

ECDSA 可提供更好的性能,是一种比 RSA 更安全的加密算法,从而可在传输层安全性 (TLS) 性能和可伸缩性十分重要的情况下提供极佳选择。 .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) 中存储始终加密列主密钥。 借助此支持,客户可以利用存储在 HSM 中的非对称密钥,而不必编写自定义列主密钥存储提供程序并在应用程序中注册它们。

客户需要在应用服务器或客户端计算机上安装 HSM 供应商提供的 CSP 提供程序或 CNG 密钥存储提供程序,才能访问使用存储在 HSM 中的列主密钥保护的 Always Encrypted 数据。

改进了 AlwaysOn 的 MultiSubnetFailover 连接行为

SqlClient 现在可自动提供与 AlwaysOn 可用性组 (AG) 之间的更快连接。 它以透明方式检测应用程序是否连接到不同子网上的 AlwaysOn 可用性组 (AG),快速发现当前的活动服务器并提供与服务器之间的连接。 在此版本之前,应用程序必须将连接字符串设置为包括 "MultisubnetFailover=true",以指示它已连接到 AlwaysOn 可用性组。 如果未将连接关键字设置为 true,则应用程序可能会在连接到 AlwaysOn 可用性组时遇到超时。 使用此版本时,应用程序无需再将 MultiSubnetFailover 设置为 true。 有关对 Always On 可用性组的 SqlClient 支持的详细信息,请参阅对高可用性、灾难恢复的 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 示例 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::GetInMemorySymbolsLengthICorProfilerInfo7::ReadInMemorySymbols),可为这些探查器工具提供对内存中 PDB 数据的访问。通过使用新 API,探查器可以采用字节数组形式获取内存中 PDB 的内容,然后对它进行处理或将它序列化到磁盘。

  • 使用 ICorProfiler 接口可更好地检测。

    使用 ICorProfiler API 的 ReJit 功能进行动态检测的分析器现在可以修改某些元数据。 以前这类工具可以随时检测 IL,但只能在模块加载时修改元数据。 因为 IL 引用元数据,所以这会限制可以进行的检测的种类。 我们通过添加 ICorProfilerInfo7::ApplyMetaData 方法来支持在模块加载之后编辑元数据的子集(特别是通过添加新的 AssemblyRefTypeRefTypeSpecMemberRefMemberSpecUserString 记录),解除了其中一些限制。 通过此更改可以进行范围广得多的动态检测。

本机映像生成器 (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 和 Web Pages 统一至称为 MVC 6 的单个 Framework。 通过 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-returning 模型绑定方法。 此功能使得 Web 窗体开发人员在使用较新版本的 ORM(包括实体框架)时,能获得异步的可伸缩性优点以及数据绑定系统的易用性。

      异步模型绑定由 aspnet:EnableAsyncModelBinding 配置设置控制。

      <appSettings>
          <add key=" aspnet:EnableAsyncModelBinding" value="true|false" />
      </appSettings>
      

      在定位 .NET Framework 4.6 的应用程序中,默认值为 true。 在定位旧版 .NET Framework 但在 .NET Framework 4.6 上运行的应用程序中,默认值为 false。 可以通过将配置设置设置为 true 来启用它。

    • HTTP/2 支持 (Windows 10)

      HTTP/2 是新版的 HTTP 协议,提供更好的连接利用率(客户端和服务器之间的往返更少),从而减少为用户加载网页的延迟。 网页(而不是服务)从 HTTP/2 中获益最多,因为该协议优化多个作为单个体验的一部分进行请求的项目。 已向 .NET Framework 4.6 中的 ASP.NET 添加了 HTTP/2 支持。 因为网络功能存在于多个层,所以 Windows、IIS 和 ASP.NET 中均需要新功能以启用 HTTP/2。 必须在 Windows 10 上运行,以便将 HTTP/2 与 ASP.NET 搭配使用。

      HTTP/2 也受到支持,默认情况下在使用 System.Net.Http.HttpClient API 的 Windows 10 通用 Windows 平台 (UWP) 上使用。

      为了提供一种方法来使用 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 支持中受益(如果你的服务器支持它)。

    • 对令牌绑定协议的支持

      Microsoft 和 Google 一直在针对身份验证的新方法进行合作,这种方法称为令牌绑定协议。 前提是罪犯可以盗取并使用身份验证令牌(在你的浏览器缓存中)以访问本应安全的资源(例如你的银行帐户),而无需知道密码或任何其他特权。 新协议旨在缓解此问题。

      令牌绑定协议将在 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,SQL Server 可对加密数据执行操作,并且最重要的是,加密密钥与应用程序一起驻留在客户的受信任环境内,而不是驻留在服务器上。 Always Encrypted 可确保客户数据的安全,因此 DBA 没有纯文本数据的访问权限。 数据的加密和解密都在驱动程序级别以透明方式执行,从而将现有应用程序必须做出的更改减至最少。 有关详细信息,请参阅 Always Encrypted(数据库引擎)Always Encrypted(客户端开发)

  • 托管代码的 64 位 JIT 编译器

    .NET Framework 4.6 采用新版 64 位 JIT 编译器(最初代码名为 RyuJIT)。 新的 64 位编译器相较旧的 64 位 JIT 编译器具有显著的性能提升。 新的 64 位编译器针对 .NET Framework 4.6 上运行的 64 位进程而启用。 如果你的应用被编译为 64 位或 AnyCPU 并在 64 位操作系统上运行,则它将在 64 位进程中运行。 虽然已采取谨慎的措施来使到新编译器的转换尽可能透明,但行为也可能发生变化。

    新的 64 位 JIT 编译器还包括硬件 SIMD 加速功能,结合 System.Numerics 命名空间中支持 SIMD 的类型使用时,可以获得良好的性能提升。

  • 程序集加载程序改进

    通过在加载相应的 NGEN 映像后卸载 IL 程序集,程序集加载程序现在能更有效地利用内存。 此更改会降低虚拟内存(这对诸如 Visual Studio 等的大型 32 位应用特别有益),还会节省物理内存。

  • 基类库更改

    为了启用关键方案,已向 .NET Framework 4.6 添加了许多新 API。 这些包括以下更改和添加:

    • IReadOnlyCollection<T> 实现

      其他集合实现 IReadOnlyCollection<T>,例如 Queue<T>Stack<T>

    • CultureInfo.CurrentCulture 和 CultureInfo.CurrentUICulture

      CultureInfo.CurrentCultureCultureInfo.CurrentUICulture 属性现在是读写而不是只读。 如果你向这些属性分配一个新 CultureInfo 对象,则由 Thread.CurrentThread.CurrentCulture 属性定义的当前线程区域性和由 Thread.CurrentThread.CurrentUICulture 属性定义在当前 UI 线程区域性也会更改。

    • 垃圾回收 (GC) 增强功能

      GC 类现在包括允许你在执行关键路径期间禁止垃圾回收的 TryStartNoGCRegionEndNoGCRegion 方法。

      GC.Collect(Int32, GCCollectionMode, Boolean, Boolean) 方法的新重载允许你控制小型对象堆和大型对象堆是否均扫频和压缩或仅扫频。

    • 启用了 SIMD 的类型

      System.Numerics 命名空间现在包括许多支持 SIMD 的类型,如 Matrix3x2Matrix4x4PlaneQuaternionVector2Vector3Vector4

      由于新的 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 时间或将 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、TaskTask<TResult> 对象的应用,请继承调用线程的区域性和 UI 区域性。 面向早期 .NET Framework 版本或不面向特定版本的 .NET Framework 的应用的行为不受影响。 有关详细信息,请参阅 CultureInfo 类主题中的“区域性和基于任务的异步操作”一节。

      System.Threading.AsyncLocal<T> 类允许你表示对于给定异步控制流(如 async 方法)来说是本地数据的环境数据。 它可用于跨线程保存数据。 你还可以定义一个回调方法,该回调方法在环境数据发生变化时就会发出通知,而不论环境数据发生变化的原因是 AsyncLocal<T>.Value 属性显式更改还是线程遇到上下文转换。

      三种便利方法(Task.CompletedTaskTask.FromCanceledTask.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 改进

      在 .NET Framework 4.6 中,WPF 现提供更出色的 HDPI 支持。 已对布局舍入进行了更改,以减少带边框的控件中的剪切实例。 默认情况下,仅当 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"/>
      

      已向 System.Windows.Input.Cursor 添加了对基于 DPI 设置自动加载右侧光标的支持。

    • 触摸更好

      在 .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 支持

      将 NetTcp 用于传输安全和客户端身份验证时,除了 SSL 3.0 和 TLS 1.0,WCF 现在还支持 SSL 版本 TLS 1.1 和 TLS 1.2。 现在可选择要使用的协议,或禁用旧的次要安全协议。 可以通过设置 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 限制:

      默认情况下,ServicePointManager.ReusePort 属性为 false,除非 HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 注册表项的 HWRPortReuseOnSocketBind 值设置为 0x1。 若要对 HTTP 连接启用本地端口重用,请将 ServicePointManager.ReusePort 属性设置为 true。 这将导致来自 HttpClientHttpWebRequest 的所有传出 TCP 套接字连接使用新的 Windows 10 套接字选项 SO_REUSE_UNICASTPORT,该选项将启用本地端口重用。

      调用 Socket.SetSocketOption 等方法时,编写仅限套接字的应用程序的开发人员可以指定 System.Net.Sockets.SocketOptionName 选项,以便出站套接字在绑定期间重用本地端口。

    • 对国际域名和 PunyCode 的支持

      一个新属性 IdnHost 已添加到了 Uri 类,以更好地支持国际域名和 PunyCode。

  • 在 Windows 窗体控件中调整大小。

    此功能已在 .NET Framework 4.6 中展开,以包括绘制 UITypeEditor 时所使用的 Bounds 属性所指定的 DomainUpDownNumericUpDownDataGridViewComboBoxColumnDataGridViewColumnToolStripSplitButton 类型和矩形。

    这是一项可以选择使用的功能。 若要启用它,在应用程序配置 (app.config) 文件中将 EnableWindowsFormsHighDpiAutoResizing 元素设置为 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 编译应用。 有关探讨与 JIT 编译和 NGEN 的差别以及对你的代码的意义的 .NET Native 概述,请参阅 .NET Native 和编译

使用 Visual Studio 2015 或更高版本进行编译时,默认将应用程序编译为本机代码。 有关详细信息,请参阅 .NET Native 入门

为了支持调试 .NET Native 应用,已向非托管调试 API 添加大量新的接口和枚举。 有关详细信息,请参阅调试(非托管 API 参考)主题。

.NET Framework 4.5.2 中的新增功能

.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 基类中的新增功能和增强包括:

Windows 窗体的改进包括:

  • 在 Windows 窗体控件中调整大小。 你可以使用系统 DPI 设置调整控件(例如,显示在属性网格中的图标)组件的大小,方法是使用应用的应用程序配置文件 (app.config) 中的条目选择使用该功能。 此功能当前在以下 Windows 窗体控件中受支持:

    若要启用此功能,请将新 <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> 元素

  • 类型反射支持 TypeTypeInfo 类之间的拆分。 请参阅 .NET Framework 中用于 Windows 应用商店应用的反射

Managed Extensibility Framework (MEF)

在 .NET Framework 4.5 中,Managed Extensibility Framework (MEF) 新增了以下功能:

  • 对泛型类型的支持。

  • 利用基于约定的编程模型,你可以基于命名约定而非特性创建各个部分。

  • 多个范围。

  • 创建 Windows 8.x 应用商店应用时可以使用一部分 MEF。 此子集可作为 NuGet 库中的可下载程序包提供。 若要安装此程序包,请在 Visual Studio 中打开项目,从“项目”菜单中选择“管理 NuGet 包”,然后联机搜索 Microsoft.Composition 程序包。

有关详细信息,请参阅 Managed Extensibility Framework (MEF)

异步文件操作

在 .NET Framework 4.5 中,已向 C# 和 Visual Basic 语言添加新的异步功能。 这些功能将添加用于执行异步操作的基于任务的模型。 若要使用此新模型,请使用 I/O 类中的异步方法。 请参阅异步文件 I/O

工具

在 .NET Framework 4.5 中,使用资源文件生成器 (Resgen.exe),可以通过 .NET Framework 程序集中嵌入的 .resources 文件创建用于 Windows 8.x 应用商店应用的 .resw 文件。 有关详细信息,请参阅 Resgen.exe(资源文件生成器)

利用按托管配置优化 (Mpgo.exe) 工具,你可以通过优化本机映像程序集来改进应用程序的启动时间、内存使用率(工作集大小)和吞吐量。 该命令行工具会针对本机映像应用程序程序集生成配置文件数据。 请参阅 Mpgo.exe(按托管配置文件优化工具)。 自 Visual Studio 2013 起,可以使用 Mpgo.exe 优化 Windows 8.x 应用商店应用和桌面应用程序。

并行计算

.NET Framework 4.5 新增了多项有关并行计算的功能和改进。 其中包括改进的性能、增强的控件、对异步编程的增强支持、新的数据流库以及对并行调试和性能分析的增强支持。 请参阅“使用 .NET 进行并行编程”博客中的 .NET Framework 4.5 中有关并行的新增功能条目。

Web

ASP.NET 4.5 和 4.5.1 为 Web 窗体、WebSocket 支持、异步处理程序、性能增强和许多其他功能添加了模型绑定。 有关更多信息,请参见以下资源:

网络连接

.NET Framework 4.5 新增了 HTTP 应用程序的编程接口。 有关详细信息,请参阅新的 System.Net.HttpSystem.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 命名空间。

  • 双重模式套接字支持。 有关更多信息,请参见 SocketTcpListener 类。

Windows Presentation Foundation (WPF)

在 .NET Framework 4.5 中,Windows Presentation Foundation (WPF) 在以下几个领域进行了更改和改进:

  • 利用新的 Ribbon 控件,你可以实现承载快速访问工具栏、应用程序菜单和选项卡的功能区用户界面。

  • 支持同步和异步数据验证的新 INotifyDataErrorInfo 接口。

  • VirtualizingPanelDispatcher 类的新功能。

  • 通过在非 UI 线程上访问集合,改进了在显示大型分组数据集时的性能。

  • 针对静态属性的数据绑定、针对实现 ICustomTypeProvider 接口的自定义类型的数据绑定,以及从绑定表达式中检索数据绑定信息。

  • 在值发生更改时重新定位数据(实时数据整理)。

  • 能够检查项目容器的数据上下文是否已断开连接。

  • 能够设置属性更改和数据源更新之间的时间间隔。

  • 改进了对实现弱事件模式的支持。 此外,事件现在可以接受标记扩展。

Windows Communication Foundation (WCF)

为了更轻松地编写和维护 Windows Communication Foundation (WCF) 应用程序,.NET Framework 4.5 中新增了以下功能:

  • 简化生成的配置文件。

  • 对协定优先开发的支持。

  • 能够更轻松地配置 ASP.NET 兼容模式。

  • 对默认传输属性值的更改,可减小你必须设置这些值的可能性。

  • XmlDictionaryReaderQuotas 类进行更新,可减小你必须手动为 XML 字典读取器配置配额的可能性。

  • 作为生成过程的一部分,由 Visual Studio 验证 WCF 配置文件,以便你可以在运行应用程序之前检测配置错误。

  • 新的异步流支持。

  • 新的 HTTPS 协议映射,使你能够更轻松地通过 Internet Information Services (IIS) 在 HTTPS 上公开终结点。

  • 能够通过将 ?singleWSDL 追加到服务 URL,来在单个 WSDL 文档中生成元数据。

  • WebSockets 支持,通过端口 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 更新为包含:

    • 对状态设置断点的能力。

    • 在工作流设计器中复制和粘贴转换的能力。

    • 对共享的触发器转换创建的设计器支持。

    • 创建状态机工作流的活动,包括:StateMachineStateTransition

  • 增强的工作流设计器功能如下:

    • 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)。 项目中的可用类型和成员自动限制为这些平台中的公共类型和成员。 有关详细信息,请参阅可移植类库

请参阅