One cornerstone of Universal Applications is .NET Native. This is Microsoft’s “compiler in the cloud” that compiles programs in the Windows Store into machine code for every supported device.
Without a JIT compiler, users can see up to 60% savings on cold startups and 40% on warm startups. The compiler looks at the whole application, allowing it to remove unused functions. This can result in up to 30% space savings in some applications.
The second cornerstone is a concept known as “adaptive apps”. This concept revolves around being able to work with features and APIs that don’t necessarily exist on the device the application is running on. When following the correct pattern, the native compiler will remove references to APIs that don’t exist on the user’s device.
Another benefit of .NET Native is that is allows Microsoft to work at a faster cadence. Applications are statically linked to most framework libraries, meaning that you are far less likely to see a breaking change in a published application. Developers must opt in to new versions that might break the application, which means Microsoft can be somewhat less careful about breaking changes.
Finally, .NET Native allow Microsoft to automatically recompile applications when a security vulnerability is found in a framework library or a new CPU architecture is needed. The latter isn’t just theoretical, Microsoft let slip they plan on supporting a fourth CPU architecture this fall.
Debug Workflow
Be default, Windows 10 applications will compile to IL in debug mode and native in release mode. This can be changed using a compiler flag exposed via the project properties window. Developers are expected to use debug mode most of the time because the build time for .NET Native is significantly longer.
When debugging on a device, Visual Studio will need to push an extra library called CoreCLR. This contains a lot of functionality that applications don’t normally need so it won’t be included when the application is installed from the Windows Store.
Versioning
In Universal Applications, developers will no longer be allowed to use four-digit version numbers. While developers can continue to use the first three digits, the fourth digit is reserved for the .NET Native compiler.
Any CPU
For Universal Applications, developers cannot specify Any CPU as a target architecture. Microsoft want application developers to actually test their applications against the target hardware.
AppX Packaging Options
Debug packages contain MSIL based libraries. Debug builds are not appropriate for side-loading onto devices because the device may not have the right version of the framework libraries.
Release packages will contain the natively compiled libraries with metadata needed for publication.
Runtime Directives (rd.xml)
Runtime Directives are used to tell the compiler which types you are accessing via reflection. If you don’t list the types correctly, the optimizer may remove the metadata on your types or even the type itself.
The downside of specifying too much in the runtime directive file is that you’ll unnecessarily increase the size of your application. If this isn’t a concern, you can retain everything using the default setting.
.NET Native Best Practices
Develop your applications in debug mode for quicker build and test cycles.
Periodically test in Release mode to ensure that .NET Native related bugs are not introduced. Don’t wait until the end of a project to try to work through native issues.
.NET Native Backlog
In the future Microsoft would like to reduce the build time for natively compiled applications. They also want to find a way to share framework packages in order to reduce the size of applications on disk.
Post Mortem Debugging
If your application crashes on a device you don’t have access to, you’ll need to get the debug symbols from the Developer portal. Using these symbols will require matching source code, so ensure that you have a matching branch.
Libraries
Windows 10 Universal Applications will have the same surface area as Windows 8.1. “And yes, WCF will work on Windows Phone.” Future releases for Universal Applications will be shipped out-of-band via NuGet.
Portable Class Libraries will work as-is if they target .NET Core 4.5.1.
Call to Action
Microsoft wants to know as soon as possible if there are any behavior differences between normal and .NET Native compilations. Report problems to dotnetnative@microsoft.com.
For more information on Universal Applications, watch the Channel 9 video, Deep Dive into XAML and .NET Universal Windows App Development.