A first hand look from the .NET engineering teams
Today, we’re announcing the availability of the .NET Framework 4.5.1 and Visual Studio 2013 (Soma’s blog). You can download these releases, now:
The .NET Framework 4.5.1 is a customer-focused release, based on feedback we’ve collected from UserVoice and other sources. In this post, we will highlight the top features that come with the release. If you want even more details, our earlier .NET Framework 4.5.1 Preview post provides an in-depth description of the release.
Check out the Visual Studio Team blog for more information on Visual Studio 2013. The ASP.NET Team blog is also a good resource for new ASP.NET features available in Visual Studio 2013 and in the .NET NuGet feed.
We heard many requests to make .NET development easier since our last release. We’re happy to report that we delivered a lot of new features to help with that, many of which were built in concert with the Visual Studio Diagnostics team.
X64 edit and continue was our most requested feature for this release. In the image below, you see a 64-bit app that is stopped at a breakpoint, with source that has been edited, and is in an invalid state. Once I finish editing the source to a valid state, I can step again (ex: F11) and then continue running my app.
Managed return values was another commonly requested feature that we delivered in this release. It allows you to write code the way you want, without having to worry about the difficulty of debugging method invocations that are passed as parameters to other methods.
Async aware debugging was the next step for us in delivering on the value of our Task-based Asynchronous Pattern. The call-stack Windows in Visual Studio 2013, when run on Windows 8.1 or Windows Server 2012 R2, now delivers the method frames in the order you expect. That’s a big step forward for async development.
ADO.NET connection resiliency is a bit of a magic feature in this release. It doesn’t come with any new APIs to use. Instead, it’s a new capability of .NET that you get “for free”. Idle connection resiliency re-builds broken idle connections to SQL databases transparently, so that you don’t have to write the code to do that.
Under the covers, this new feature provides a robust connectivity system for recreating broken connections and re-trying transactions. It supports both synchronous and asynchronous operations, so it can be used with a variety of code patterns.
Here’s some simple ADO.NET code that we used to demonstrate this feature:
SqlCommand command = new SqlCommand(queryString, Program.SqlConnection);
SqlDataReader reader = null;
// Fetch the results
reader = command.ExecuteReader();
// Let the user know something went wrong with the connection
It’s part of an app that finds contacts from a SQL Server database. Let’s assume that we’ve started the app, on the .NET Framework 4.5 (not 4.5.1), and that we’ve searched for a few contacts. To mimic the scenario of losing a connection, we intentionally break the connection to the database for the app, with TCPView.
Here’s what happens when we search for the next contact. Tom, we’re out of luck! The database connection was lost.
When we run the exact same app, with no additional configuration on the .NET Framework 4.5.1, we see a much better experience. We close the connection again, in the same way. However, after that, we’re able to find “Tom” in the contacts database! You can see that ADO.NET re-connects to the database automatically. The green highlighted line in TCPView indicates a new connection was created. You can see that the process name is the same. ADO.NET re-created that connection. As you saw in the code above, there’s no logic to cover that case, but only to display an error message.
Performance is always an important focus for the .NET team. We added some core features that will help larger scale apps, with a focus on ASP.NET.
ASP.NET App Suspend is a bold new approach for shared hosting for .NET apps. It uses the combination of memory (RAM) and storage (HDD or SSD) in a new way that is inspired by the app suspend technologies in Windows Phone and Windows Store. It makes ASP.NET sites much more responsive and enables you to host more sites on a single server. It is very well suited for commercial web hosters, like Windows Azure Web Sites, and Enterprise IT web hosting.
We conducted a few experiments to run ASP.NET App Suspend through its paces, in our performance lab. I’ve included the results of one of those experiments in the chart below, with DotNetNuke (DNN). Check out our blog post on ASP.NET App Suspend to see the full set of perf numbers,
Check out this video to see the experiment that led to the numbers above. Pretty impressive perf improvement. No code changes required!
Multi-core JIT (MCJ) for ASP.NET is another scenario that we enabled this release, building on our earlier client MCJ solution. In the .NET Framework 4.5.1 release, we enabled MCJ for scenarios that rely on Assembly.LoadFrom and Appdomain.AssemblyResolve. These APIs are not specific to ASP.NET, but they show up a lot in the ASP.NET apps we tested, so they were necessary to make work with MCJ.
We used DotNetNuke again, to test the benefit of MCJ. You can see the results in the image below. You’ll see that the startup time is similar to what we saw above, with ASP.NET App Suspend. We tested a different page, so the “cold startup” number is a bit different. Here, we see an ~20% startup improvement. In the cold startup case, the app spends 852ms JITing. In the MCJ case, foreground JIT is reduced to 428ms, since 429ms (50%) of JITing can be done concurrently in the background. A 50% cut in JIT time is a good thing!
You might be wondering why you would use MCJ when you can use ASP.NET App Suspend instead. The App Suspend numbers look way better. Well, ASP.NET App Suspend only kicks in after the app has started once, and servers do need to be rebooted sometimes. So, our advice going forward is to use both MCJ and ASP.NET App Suspend, together. MCJ will improve the cold startup case, and then App Suspend will kick in after that, if your site hits the Idle time-out value. The two features work together nicely, as complementary solutions to the same problem.
The great thing about MCJ is that it is enabled by default for ASP.NET in the .NET Framework 4.5.1. You don’t need to do anything to turn it on, other than upgrade your server to use the .NET Framework 4.5.1. It is opt-in for client apps.
On-demand Large Object Heap (LOH) compaction is another requested feature that we delivered this release. The LOH is a heap used by the Garbage Collector (GC) for objects that are >= 85,000 bytes. Those objects are often (large) arrays. Until this release, the LOH did not have a compaction mechanism, which could lead to fragmentation over time. Fragmentation can occur when apps use large amounts of memory – at least hundreds of megabytes – and allocations are both large (objects that are >= 85,000 bytes) and temporary. On 32-bit systems, processes can run out virtual address space due to fragmentation, which results in OutOfMemory (OOM) exceptions. On 64-bit systems, running out of virtual address space is much less likely. Most apps do not run into this problem because they do not make extensive use of the LOH and the small object heaps (SOH) have automatic heap compaction built-in.
In this release, we delivered on-demand compaction for the LOH, which is useful for mitigating LOH fragmentation causing OOM. It is exposed as a GC Settings API. Since compaction moves large amounts of memory, which is expensive – GC pause times >1s – you should only use this unless your app has experienced OOMs due to fragmentation. That’s why we exposed an on-demand mechanism instead of an automatic one. With prudent use, it can be a great tool to reduce fragmentation and avoid running out of virtual address space (OOM). It is also not intended as general feature for reducing memory use.
In the image below, you can see an abstract example of an LOH memory segment that is fragmented. After compaction, you can see that the memory consumed by active objects (in blue) and the free memory (in white) have been separated.
The win is that the free memory is now in one contiguous range and is able to satisfy much larger allocation requests than it could before. That means that an app will use less virtual address space, since fragmentation can be kept to a more manageable level, and memory is generally used more efficiently.
We’re now delivering software faster. The .NET Framework 4.5.1 was delivered about a year after the .NET Framework 4.5. That’s pretty fast for a mature framework. For even faster releases, we use NuGet.org. You can see that we have released quite a few .NET NuGet Packages available already. It’s not just something that we started recently.
.NET NuGet releases have been plentiful over the past year, since we released the .NET Framework 4.5. If we look a traffic to this blog and also to our @dotnet twitter account, we can see that there is a lot of interest in targeted releases that fill key gaps. Thanks for the support on this new approach. The following are the NuGet releases that have gone out since 4.5 RTM.
We’re happy to see high traffic numbers to our release announcements and to our download pages. Even more important is that NuGet releases enable us to have a higher-level of engagement with you, our developer customers. It’s somehow unintuitive that shorter releases would allow more feedback to get into the product, but it’s true. If you look at our blog posts for our NuGet releases, you’ll see multiple cases where we publically made product changes based on direct customer feedback. Here’s a favorite example, where we (temporarily) pulled ImmutableArray<T> from our ImmutableCollection package. This was based on your feedback and results in very high quality releases. We cannot wait to see where we are one year from now.
Better discoverability of Microsoft .NET NuGet packages was a key goal for us. Half a year ago, the NuGet client, which comes with Visual Studio, had a single view onto the entire NuGet catalog. That didn’t make much sense to us. We would talk to customers about the NuGet packages that we had released. They’d be interested to try out those releases, but that would be the first time they’d heard about them. We knew that we had a discoverability problem.
The NuGet team came to the rescue. We now have a “Microsoft and .NET” feed within the NuGet client. It’s the same feed that you can see on our .NET NuGet Packages page. You can use that feed, in either location, to find all of the libraries that the .NET team has released. Please try them out and give us feedback.
The screenshot below is the NuGet client in Visual Studio 2013.
Supporting enterprise use of .NET NuGet packages was an important goal of this release. We wanted to extend the expectation of a high quality level and the support and servicing model that we already have with the .NET Framework to our .NET NuGet packages. To achieve that, we used the .NET NuGet feed described above as the focus for this effort. We’ve been adding our packages to the feed, and have ensured that each one of them meet the same quality bar as the .NET Framework. If you stick to stable releases in our feed, then are using NuGet as a supported .NET Framework release vehicle.
We also had major feature ask from some of our larger corporate customers, to enable Microsoft Update servicing of our .NET NuGet packages. In corporate/enterprise environments, we see .NET apps being installed thousands of times, on client machines and web farms. Those customers are happy depending on the .NET Framework, since they know it has a strong servicing mechanism, via MU. That’s one of the reasons they choose .NET, actually. Up until now, we had not extended that servicing model to our NuGet packages, which presented a blocker to those customers, and that’s exactly what they told us.
Starting with the .NET Framework 4.5.1, we have extended our MU servicing model to our .NET NuGet Packages. Going forward, you can deploy apps on desktops and servers that use our NuGet packages and feel confident that we’ll service them via MU. The only likely time we’ll service NuGet files via MU is to patch a critical security vulnerability. We’ve never found the need to do that, however, we do think it is a good idea to have this extra measure available to use. NuGet.org remains our primary vehicle for NuGet package updates, even in the case of critical security updates.
The .NET Framework 4.5.1 is a big release with many new great features to try out. We covered several areas of the product, such as developer productivity, app performance and shipping releases faster. We’ve had great feedback since our Preview release. Now that the final release of the .NET Framework 4.5.1 is available, please do install it and Visual Studio 2013 and try out the new features.
The following are the UserVoice requests that have been closed as completed this release:
While the latest releases are out, please don’t hesitate to give us feedback. We’re on a faster release cadence now, and would appreciate your feedback as we consider what to do next. The best places are UserVoice, Visual Studio Connect and the comment to this post. We’re also listening on Twitter and Facebook.
Congratulations and thanks for the hard work.
Such a great time to be a .NET developer.
Cool stuff. Async aware debugging, DB reconnection & X64 edit & continue in debug mode really awesome features. Gr8 job guys.
Good job. Now you just need to remove the IE10 requirement!!!
Apparently, Windows Desktop edition doesn't really need it. You can just install IE10, the VS2013 and then remove IE10 and VS will work just fine.
There are still places in the world, where IE10 is not allowed by it-department.
I'm one of the lucky ones, where I can temporarily install it, but I have to remove it again since it breaks compatibility with many of our intranet-sites.
Congratulations! Proud and Great to be .Net developer
Thank you guys and congratulations.
@.Net team, can you guys please implement String.FirstIndexOf() to complement String.LastIndexOf() ?
Compare these two:
char lastInSequence = "awesomeness".LastIndexOf('s');
char firstInSequence = "awesomeness".TakeWhile(c => c == 's').Count();
I know there must a be a very good explanation why its not there in first place, but its really important.
int lastIndex = "awesomeness".LastIndexOf('s');
int firstIndex = "awesomeness".TakeWhile(c => c == 's').Count();
@The Deeds: I think you are looking for <a href="msdn.microsoft.com/.../a>, which has been available since the first release.
@John, there is a difference between IndexOf and FirstIndexOf.
@The Deeds: What would be the difference between IndexOf and FirstIndexOf? IndexOf should be exactly what you're looking for.
Also, your TakeWhile implementation incorrectly returns 0.
thank you guys ... for ever in code ... code is easy but life is hard ...
@The Deeds, @Gordon,
"awesomeness".LastIndexOf('s'); // returns 10
"awesomeness".TakeWhile(c => c != 's').Count(); // "first index of" returns 3
"awesomeness".IndexOf('s') ;// returns 3
Really this is good job,Cool stuff.
Web Cyber Tech
visual studio sin duda el mejor para el desarrollo de aplicaciones, excelente =)
Can anyone please help me with this? stackoverflow.com/.../1712065
Not sure where else to post this, but I installed the .NET Framework 4.5.1 on a Windows Server 2012 Standard box and I'm still not able to see the Idle Time-out Action in IIS 8.0 on an application pool. Am I missing something?