之前一文《c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥》 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方信息的翻译开始做起。
此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题。本文是第三个主题:.NET Native部署测试及样例。
向导文链接:《C++的性能C#的产能?! - .Net Native 系列:开发向导》
[小九的学堂,致力于以平凡的语言描述不平凡的技术。如要转载,请注明来源:小九的学堂。cnblogs.com/xfuture]
原文:.NET Native Getting Started
.NET Native部署测试及样例
.NET Framework 4.5
class="cl_IC101471" title="Note" src="/Upload/Images/2014050918/B89C3333A5CED2A9.gif" alt="Note" /> 小贴士
这个主题依赖于预发行的.net native开发者预览版。下载地址: Microsoft Connect website. 友情提示需要注册..
开发流程移步步骤《二 . NET Native开发流程详解》
部署及测试:
当你开发流程结束,配置成功.Net Native Tools并且更新了运行时指令文件, 你可以开始重建和部署测试你的应用。.Net Native 原生的二进制文件放置在项目属性配置的生成输出目录的子目录ILC.out中。若没有这个文件夹,则说明该项目并没有被.Net Native成功编译。
.Net Native 目前支持x64和arm框架,所以你只能部署该应用程序到相应的设备中。之后您需要在该设备上进行测试和解决故障。
如果你的应用程序不能正常运行(尤其是运行时抛出了MissingMetadataException或MissingInteropDataException异常),您需要按照下一块内容:手动解决缺少元数据异常。启动First-chance exception(程序产生了异常并被捕获,继续运行) 可以帮助您发现这些bugs。
经过了测试和调试错误,您已经对上述的异常进行很好的处理后,应该测试一些性能优化情况。要做性能测试,必须要将项目构建从debug改成release,测其发行版本。
常见的问题:
.net native 最常见的问题就是遇到MissingMetadataException了。该异常会导致程序出现不可预测的行为甚至崩掉。本节来讨论如何通过在运行时添加指令来进行调试和解决此类型的异常。有关运行指令格式相关的信息,请参照:Runtime Directives (rd.xml) Configuration File Reference.当你添加好运行指令后,你可以部署和测试你的应用程序并且解决元数据的相关异常。
注意: 添加指令并不应该更改底层代码,应该在较高层次集中处理。建议在命名空间或者类型初添加指令,而不是每一块代码段。添加指令后机器码项目编译时间也会增长。
当处理元数据丢失的异常时,应考虑如下问题:
1. 应用程序做了什么导致了这个异常? 例如它是否是数据绑定?还是序列化和反序列化拿到数据?或者是反射?
2. 这个异常是否是普遍的?例如当序列化一个对象时产生了该异常,你就需要每一个序列化的部分都来检查测试一下了。
3. 尽量少的用反射。重构代码,将反射部分尽可能的更换机制。
测试中遇到问题的样例:
Example: Handling Exceptions When Binding Data
这个例子是一个.Net Native项目当绑定数据时遇到的MissingMetadataException异常。异常信息如下:
This operation cannot be carried out as metadata for the following type was removed for performance reasons: App.ViewModels.MainPageVM
下面是相关栈调用的信息:
Reflection::Execution::ReflectionDomainSetupImplementation.CreateNonInvokabilityException+0x238 Reflection::Core::ReflectionDomain.CreateNonInvokabilityException+0x2e Reflection::Core::Execution::ExecutionEnvironment.+0x316 System::Reflection::Runtime::PropertyInfos::RuntimePropertyInfo.GetValue+0x1cb System::Reflection::PropertyInfo.GetValue+0x22 System::Runtime::InteropServices::WindowsRuntime::CustomPropertyImpl.GetValue+0x42 App!$66_Interop::McgNative.Func_IInspectable_IInspectable+0x158 App!$66_Interop::McgNative::__vtable_Windows_UI_Xaml_Data__ICustomProperty.GetValue__STUB+0x46 Windows_UI_Xaml!DirectUI::PropertyProviderPropertyAccess::GetValue+0x3f Windows_UI_Xaml!DirectUI::PropertyAccessPathStep::GetValue+0x31 Windows_UI_Xaml!DirectUI::PropertyPathListener::ConnectPathStep+0x113
这个应用是WPF程序,Xaml中的空间元素(View)通过绑定和PropertyInfo.GetValue来通过类型拿到上下文数据载体(ViewModel)属性的值。但是这个属性的元数据丢失了,所以报出了元数据丢失的异常。
解决方案:
第一步设置该对象是可序列化的,保证其是可访问的:
<Type Name="App.ViewModels.MainPageVM" Serialize="Required Public" />
第二步考虑其是否为普遍问题。在本例中所有viewmodel都存在该问题,所以不应一次只修改一个地方后就继续进行调试。由于所有viewmodel都在app.viewmodels里所以可以进行如下设置:
<Namespace Name="App.ViewModels " Serialize="Required Public" />
由于数据绑是基于反射的,所以无法通过更改代码方式来避免反射。但有一些方法可以做到在编译时就将view和viewmodel关联起来,不依赖运行时来保存元数据。例如可以设置Windows.UI.Xaml.Data.BindableAttribute 属性,它会让编译器在编译时关联上下文,避免使用运行时Default.rd.xml序列化来拿元数据。
有关rd.xml可以参阅Runtime Directives (rd.xml) Configuration File Reference.
在开发中可能会遇到更多的问题,可以MSDN论坛来进行发问。
若想查看该系列前几篇可以点击: 向导