最近完成一款UWP应用,在手机端测试发布版(Release)的时候应用莫名奇妙的强行关闭,而同样的应用包在PC端一点问题都没有,而且Debug版在两个平台都没有问题,唯独手机的Release版有问题。实在没办法只能记录每个步骤的Log,通过查看Log发现是SuspensionManager的DataContractSerializer序列化抛出了ArgumentNullException异常。

常见.NET Native引发异常:

例1:

System.InvalidCastException: InvalidCast_Com
at SharedLibrary!<BaseAddress>+0x429e9d
例2:
HResult : -2146233088 TypeName : Newtonsoft.Json.JsonException, Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed Message : Newtonsoft.Json.JsonException: Error creating 'NestedObjectJsonConverter'. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Newtonsoft.Json.Serialization.JsonTypeReflector.<>c.b__18_1(Object param) at
例3:
Exception thrown: 'System.AggregateException' in System.Private.Threading.dll
Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll
Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll
Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll
The thread 0x2a30 has exited with code 0 (0x0).
Exception thrown: 'System.Reflection.MissingMetadataException' in System.Private.Reflection.Core.dll
Additional information: 'Microsoft.Extensions.Caching.Memory.MemoryCacheOptions' is missing
 
原因:
因为手机Release版使用了

.Net Native

编译。.Net Native编译时将源代码转换为本机代码不再有中间语言(IL)。这也是为什么.NET Native编译的代码中发生的异常不会出现在 JIT 编译的代码中。
 
.NET Native编译做了下面几件事:
    详细介绍参照MSDN:https://msdn.microsoft.com/zh-cn/library/dn807190(v=vs.110).aspx
  • 对于某些代码路径,它将依靠反射和元数据的代码替换为静态本机代码。

  • 如果可能,它会尝试消除所有元数据。

  • 它只将实际由应用程序调用的实现代码包含在最终应用程序集中。这尤其会对第三方库和 .NET Framework 类库中的代码产生影响。因此,应用程序不再依赖第三方库或完整的 .NET Framework 类库;相反,对应用程序而言,当前第三方和 .NET Framework 类库中的代码都是本地的。

  • 它将完整的 CLR 替换为主要包含垃圾回收器的重构运行时。重构运行时位于应用程序中名为 mrt100_app.dll 本地库,且其大小仅为几百千字节。这可能是因为静态链接不再需要公共语言运行时执行多个服务。

常见问题操作:

因为 .NET Native只在获知应用程序实际调用了实现代码时才会将它链接到应用程序中,所以应用程序中可能不包含以下操作中所需的元数据或实现代码。如果在运行时缺少必需的元数据或实现代码,应用程序运行时将引发MissingMetadataExceptionMissingRuntimeArtifactExceptionMissingInteropDataException 异常。

  • 反射。

  • 动态或后期绑定调用。

  • 序列化和反序列化。

  • COM 互操作。

解决办法:

为了让.NET Native编译时不删除我们需要的元数据或者实现代码,这时需要配置Default.rd.xml(运行时指令)文件,指定程序需要的元数据。

文件地址如下图:

默认的配置为:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All"/> <!-- Add your application specific runtime directives here. --> </Application>
</Directives>

为了能正确配置建议使用这个工具:MissingMetadataException troubleshooterhttp://dotnet.github.io/native/troubleshooter/type.html#

比如配置SuspensionManager挂起中断处理(DataContractSerializer序列化)

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All"/> <Type Name="TestDemo.StudentModel" DataContractSerializer="Required Public" /> </Application>
</Directives>

MSDN介绍配置

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Namespace Name="Contoso.Cloud.AppServices" Serialize="Required Public" />
<Namespace Name="ContosoClient.ViewModels" Serialize="Required Public" />
<Namespace Name="ContosoClient.DataModel" Serialize="Required Public" />
<Namespace Name="Contoso.Reader.UtilityLib" Serialize="Required Public" /> <Namespace Name="System.Collections.ObjectModel" >
<TypeInstantiation Name="ObservableCollection"
Arguments="ContosoClient.DataModel.ProductItem" Serialize="Public" />
<TypeInstantiation Name="ReadOnlyObservableCollection"
Arguments="ContosoClient.DataModel.ProductGroup" Serialize="Public" />
</Namespace>
</Application>
</Directives>

详细节点介绍与配置参照MSDN:运行时指令 (rd.xml) 配置 https://msdn.microsoft.com/zh-cn/library/dn600639(v=vs.110).aspx

注意点:

DataContractSerializerDataContractJsonSerializerXmlSerializer 类有些特殊,有些情况需要配置有些情况不需要配置Default.rd.xml文件。
 

不需要配置情况:(构造函数中使用TypeOf指定类型时.Net Native编译器会自动处理)

DataContractSerializer dataSer = new DataContractSerializer(typeof(T));

需要配置情况:(构造函数外部使用Typeof指定类型时必须在Default.rd.xml文件配置)

Type t = typeof(DataSet); 

XmlSerializer ser = new XmlSerializer(t);

或者SuspensionManager挂起中断处理的

DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);

或者

XmlSerializer xSerializer = new XmlSerializer(typeof(Teacher),
new Type[] { typeof(Student),
typeof(Course),
typeof(Location) });

备注:

将 Windows 应用商店应用迁移到 .NET Native建议仔细阅读MSDN说明(https://msdn.microsoft.com/zh-cn/library/dn600634(v=vs.110).aspx)。

UWP开发之Mvvmlight实践六:MissingMetadataException解决办法(.Net Native下Default.rd.xml配置问题)的更多相关文章

  1. UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件

    在开发中或者后期测试乃至最后交付使用的时候,如果应用出问题了我们一般的做法就是查看Log文件.上章也提到了查看Log文件,这章重点讲解下如何查看Log文件?如何找到我们需要的Packages安装包目录 ...

  2. UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理

    最近比较忙有一段时间没有更新了,再接再厉继续分享. 案例下载:https://github.com/NewBLife/UWP/tree/master/SuspendSample 先我们看看App在生命 ...

  3. UWP开发之Mvvmlight实践二:Mvvmlight的核心框架MVVM与MVC、MVP的区别(图文详解)

    最近UWP开发在海外很潮流,随着微软收购Xamarin,我们这些C#程序员也可以靠这杆小米枪挑战Android,IOS平台了. 那我们为什么选择MVVM做UWP开发?MVC,MVP,MVVM他们之间到 ...

  4. UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

    在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...

  5. UWP开发之Mvvmlight实践八:为什么事件注销处理要写在OnNavigatingFrom中

    前一段开发UWP应用的时候因为系统返回按钮事件(SystemNavigationManager.GetForCurrentView().BackRequested)浪费了不少时间.现象就是在手机版的详 ...

  6. UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)

    在做MVVM各种框架对比之前,我觉得有必要先自己做一个简单的MVVM实现案例比较好,这样就可以看到自己实现的时候有那些不方便的地方.而各种框架又是怎么解决我们这些麻烦的. 案例介绍:用户登录画面,没有 ...

  7. UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)

    最近一直在做UWP开发,为了节省成本等等接触到MVVMlight,觉得有必要发点时间研究它的用法与实现原理才行.如果有问题的地方或者有好的建议欢迎提出来. 随着移动开发的热门,Mvvmlight在An ...

  8. UWP开发之Mvvmlight实践四:{x:bind}和{Binding}区别详解

    {x:bind}是随着UWP被推出而被添加的,可以说是Win10 UWP开发专有扩展.虽然 {x:Bind} 缺少{Binding} 中的一些功能,但它运行时所花费的时间和使用的内存量均比 {Bind ...

  9. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

随机推荐

  1. CORS详解[译]

    介绍 由于同源策略的缘故,以往我们跨域请求,会使用诸如JSON-P(不安全)或者代理(设置代理和维护繁琐)的方式.而跨源资源共享(Cross-Origin Resource Sharing)是一个W3 ...

  2. socket读写返回值的处理

    在调用socket读写函数read(),write()时,都会有返回值.如果没有正确处理返回值,就可能引入一些问题 总结了以下几点 1当read()或者write()函数返回值大于0时,表示实际从缓冲 ...

  3. 【探索】在 JavaScript 中使用 C 程序

    JavaScript 是个灵活的脚本语言,能方便的处理业务逻辑.当需要传输通信时,我们大多选择 JSON 或 XML 格式. 但在数据长度非常苛刻的情况下,文本协议的效率就非常低了,这时不得不使用二进 ...

  4. java中servlet的各种路径

    1. web.xml中<url-pattern>路径,(叫它Servlet路径!) > 要么以“*”开关,要么为“/”开头 2. 转发和包含路径 > *****以“/”开头:相 ...

  5. 【转】为什么我们都理解错了HTTP中GET与POST的区别

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...

  6. iOS从零开始学习直播之2.采集

      直播的采集由采集的设备(摄像头.话筒)不同分为视频采集和音频采集,本篇文章会分别介绍. 1.采集步骤   1.创建捕捉会话(AVCaptureSession),iOS调用相机和话筒之前都需要创建捕 ...

  7. 给缺少Python项目实战经验的人

    我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...

  8. sqlServer去除字符串空格

    说起去除字符串首尾空格大家肯定第一个想到trim()函数,不过在sqlserver中是没有这个函数的,却而代之的是ltrim()和rtrim()两个函数.看到名字所有人都 知道做什么用的了,ltrim ...

  9. iOS9支付宝无法调起客户端

    1.为了适配 iOS9.0 中的 App Transport Security(ATS)对 http 的限制,这里需要对 支付宝的请求地址 alipay.com 做例外,在 app 对应的 info. ...

  10. Netty构建分布式消息队列实现原理浅析

    在本人的上一篇博客文章:Netty构建分布式消息队列(AvatarMQ)设计指南之架构篇 中,重点向大家介绍了AvatarMQ主要构成模块以及目前存在的优缺点.最后以一个生产者.消费者传递消息的例子, ...