{"id":14795,"date":"2017-09-28T16:56:59","date_gmt":"2017-09-28T23:56:59","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/dotnet\/?p=14795"},"modified":"2021-09-29T16:39:41","modified_gmt":"2021-09-29T23:39:41","slug":"net-framework-4-7-1-runtime-and-compiler-features","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/net-framework-4-7-1-runtime-and-compiler-features\/","title":{"rendered":".NET Framework 4.7.1 Runtime and Compiler Features"},"content":{"rendered":"<p><span>This post describes the new Runtime, Compiler and Base Class Library (BCL) improvements in the .NET Framework 4.7.1.\u00a0You can try out these\u00a0features by downloading the\u00a0Developer Pack, described in the\u00a0<a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2017\/08\/07\/welcome-to-the-net-framework-4-7-1-early-access\/\">Welcome to the .NET Framework 4.7.1 Early Access blog post<\/a>.\u00a0<\/span><\/p>\n<h2>BCL &#8211; .NET Standard 2.0 Support<\/h2>\n<p>.NET Framework 4.7.1 has\u00a0built-in support for .NET Standard 2.0.\u00a0.NET Framework 4.7.1 adds about <a href=\"https:\/\/github.com\/dotnet\/\">200 missing APIs<\/a> that were part of <a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2017\/08\/14\/announcing-net-standard-2-0\/\">.NET Standard 2.0<\/a> but not actually implemented by .NET Framework 4.6.1, 4.6.2 or 4.7.\u00a0You can refer to details on .NET Standard on <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/net-standard\">.NET Standard Microsoft docs<\/a>. While libraries targeting <a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2017\/08\/14\/announcing-net-standard-2-0\/\">.NET Standard 2.0<\/a>\u00a0can be consumed by applications and libraries targeting <a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2015\/11\/30\/net-framework-4-6-1-is-now-available\/\">.NET Framework 4.6.1<\/a> and higher, not all files that are required for .NET Standard libraries were part of .NET Framework 4.6.1. In fact, .NET Framework 4.6.1 was shipped before .NET Standard 2.0 was even designed. That&#8217;s why building an application targeting .NET Framework 4.6.1, as well as .NET Framework 4.6.2 and 4.7, will have to deploy additional .NET Standard 2.0 support files.<\/p>\n<h5>Experience\u00a0in .NET Framework 4.6.1 through 4.7<\/h5>\n<ul>\n<li>If you use Visual Studio 2017 15.3 or higher,\u00a0the .NET Standard 2.0 support files are automatically copied to the application&#8217;s output folder.<\/li>\n<li>If you use Visual Studio 2015 and use <a href=\"https:\/\/dist.nuget.org\/visualstudio-2015-vsix\/v3.6.0\/NuGet.Tools.vsix\">NuGet 3.6<\/a>, we will prompt you to install a <a href=\"https:\/\/aka.ms\/netstandard-build-support-netfx\">support package<\/a> which will handle copying the support files to the output directory.<\/li>\n<\/ul>\n<h5>Experience\u00a0in .NET Framework 4.7.1<\/h5>\n<ul>\n<li>These support files no longer have to be deployed with the application &#8211; they are built right into the .NET Framework itself.<\/li>\n<li>This also removes the need for <a href=\"https:\/\/github.com\/dotnet\/standard\/issues\/481\">binding redirects<\/a> when using .NET Standard libraries on .NET Framework because the CLR automatically unifies version numbers of assemblies that are part of the platform.<\/li>\n<\/ul>\n<h2>Runtime &#8211; GC Performance Improvements<\/h2>\n<p>.NET Framework 4.7.1 brings in\u00a0changes in <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/garbage-collection\/\">Garbage Collection (GC)<\/a> to improve\u00a0the allocation performance, especially for Large Object Heap (LOH) allocations. This is due to\u00a0an architectural change to split the\u00a0heap\u2019s allocation lock into 2, for Small Object Heap (SOH) and LOH. Applications that\u00a0make\u00a0a lot of LOH allocations, should see a reduction in\u00a0allocation lock contention, and see better performance. These improvements allow LOH allocations while Background GC (BGC) is sweeping SOH. Usually the LOH allocator waits for the whole duration of the BGC sweep process before it can satisfy requests to allocate memory. This can hinder performance. You can observe this problem in PerfView&#8217;s GCStats where there is an &#8216;LOH allocation pause (due to background GC) &gt; 200 msec Events&#8217; table. The pause reason is &#8216;Waiting for BGC to thread free lists&#8217;. This feature should help\u00a0mitigate this problem.<\/p>\n<h2>Compiler &#8211; ValueTuple is Serializable<\/h2>\n<p>The System.ValueTuple types in .NET Framework 4.7.1 are now marked as Serializable, which allows binary serialization as shown in the example below.\u00a0Since the syntax for C# 7.0 and VB 15.5 tuple types, for example, (int, string) relies on System.ValueTuple, this should make migrating from System.Tuple to using the new tuple syntax easier. <\/p>\n<p><script src=\"https:\/\/gist.github.com\/preetikr\/ae66871b9af9b4cc6aaee74d8604e8e5.js\"><\/script><\/p>\n<h2>Compiler &#8211;\u00a0Support for ReadOnlyReferences<\/h2>\n<p>.NET Framework 4.7.1 adds initial support for the\u00a0<a href=\"https:\/\/github.com\/dotnet\/csharplang\/blob\/master\/proposals\/csharp-7.2\/readonly-ref.md\">ReadOnlyReferences <\/a>C# 7.2 language feature, which\u00a0 is coming in a future Visual Studio 2017 Update. .NET Framework 4.7.1 introduces the IsReadOnlyAttribute for ReadOnlyReferences feature. This attribute will be used by the compiler to mark members that have readonly-ref return types or parameters. If the compiler is running against an older .NET Framework version, it will generate this attribute and embed it&#8217;s definition in\u00a0the compiled assembly. The following\u00a0example illustrates C# 7.2 code that can make\u00a0use of this attribute. <\/p>\n<p><script src=\"https:\/\/gist.github.com\/preetikr\/7f475f5487d735639e5f334b017ee418.js\"><\/script><\/p>\n<h2>Compiler &#8211;\u00a0Support for Runtime Feature Detection<\/h2>\n<p><a href=\"https:\/\/github.com\/dotnet\/corefx\/issues\/17116\">This new\u00a0API<\/a> provides a way to detect whether a particular runtime supports a certain feature or not. At compile time the API provides a way to do that statically through reflection.\u00a0Whenever the compiler needs to check for runtime support, it would look for the corresponding well-known enum member, for instance, System.Runtime.CompilerServices.RuntimeCapabilities.SupportsDefaultImplementation. If the member exists, then the feature check is successful or the feature is supported. The value for that enum member is ignored.<\/p>\n<p>At runtime the check for feature support is done by calling a static method. This is enabled by the addition of the framework type RuntimeFeatures. Tools can query it by calling the static method bool IsSupported(string) to check whether the feature is supported or not, by passing in the string name for a given feature. For example, RuntimeFeatures.IsSupported(&#8220;FixedGenericAttributes&#8221;).<\/p>\n<p>Following\u00a0example illustrates C# 7.2 code that can make use of this attribute. <\/p>\n<p><script src=\"https:\/\/gist.github.com\/preetikr\/e558f17091813a075a22179fafa770d8.js\"><\/script><\/p>\n<h2>Runtime &#8211; Support for Portable PDBs<\/h2>\n<p>This feature adds support for Portable PDBs in the .NET Framework. Libraries that generate code at runtime, like <a href=\"https:\/\/blogs.msdn.microsoft.com\/cdndevs\/2015\/12\/01\/adding-c-scripting-to-your-development-arsenal-part-1\/\">C# Scripting<\/a>, would benefit from being able to detect whether the runtime supports Portable PDBs or not. This is because they could emit Portable PDBs instead of Windows PDBs. Emitting Portable PDBs has performance benefits; it is faster and has much smaller memory footprint. In absence of this new API the library would need to resort to hard-coding build numbers of the mscorlib or conservatively assume that\u00a0.NET Framework\u00a0doesn&#8217;t support Portable PDBs. In addition RuntimeFeature.IsSupported method would be changed to return true if &#8216;PortablePdb&#8217; is passed to it. Following sample illustrates how this can be passed. <\/p>\n<p><script src=\"https:\/\/gist.github.com\/preetikr\/b0ef5c2651b6dff92626116805d6a239.js\"><\/script><\/p>\n<h2>Closing<\/h2>\n<p><span>Try out these new features in\u00a0<a href=\"https:\/\/github.com\/Microsoft\/dotnet-framework-early-access\/blob\/master\/README.md\">.NET Framework 4.7.1 Early Access build shared<\/a>\u00a0and please provide your feedback by\u00a0<\/span><a href=\"https:\/\/github.com\/Microsoft\/dotnet-framework-early-access\/issues\/new\">reporting an issue at the .NET Framework Early Access GitHub repository<\/a><span>.\u00a0 <\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post describes the new Runtime, Compiler and Base Class Library (BCL) improvements in the .NET Framework 4.7.1.\u00a0You can try out these\u00a0features by downloading the\u00a0Developer Pack, described in the\u00a0Welcome to the .NET Framework 4.7.1 Early Access blog post.\u00a0 BCL &#8211; .NET Standard 2.0 Support .NET Framework 4.7.1 has\u00a0built-in support for .NET Standard 2.0.\u00a0.NET Framework 4.7.1 [&hellip;]<\/p>\n","protected":false},"author":364,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[],"class_list":["post-14795","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet"],"acf":[],"blog_post_summary":"<p>This post describes the new Runtime, Compiler and Base Class Library (BCL) improvements in the .NET Framework 4.7.1.\u00a0You can try out these\u00a0features by downloading the\u00a0Developer Pack, described in the\u00a0Welcome to the .NET Framework 4.7.1 Early Access blog post.\u00a0 BCL &#8211; .NET Standard 2.0 Support .NET Framework 4.7.1 has\u00a0built-in support for .NET Standard 2.0.\u00a0.NET Framework 4.7.1 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/14795","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/364"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=14795"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/14795\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=14795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=14795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=14795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}