最近完成一款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)。

最新文章

  1. sql 用union合并合并查询结果
  2. Couldn&#39;t open file on client side, trying server side 错误解决
  3. 菜鸟学Linux命令:find命令 查找文件
  4. SAP传输系统TMS、开发类、传输请求
  5. javascript的关于刷新页面给出提示框的代码
  6. [Everyday Mathematics]20150222
  7. poj 3080 Blue Jeans(水题 暴搜)
  8. junit测试用例加载spring配置文件
  9. JAVAscript——菜单下拉列表练习(阻止事件冒泡)
  10. 【转】Qt Mode/View
  11. DLL 导出类
  12. 页面异步请求会保留原有的js内容
  13. CentOS7 搭建Ambari-Server,安装Hadoop集群(一)
  14. 【angularjs】pc端使用angular搭建项目,实现导出excel功能
  15. 解决nuxt.js新建项目报错的问题
  16. 星号三角形 I python
  17. HDU 4762 Cut the Cake (2013长春网络赛1004题,公式题)
  18. android发送与接收超长短信
  19. python条件判断if&#183;&#183;&#183;else、循环while和for
  20. Ibatis.Net 各种配置说明学习(二)

热门文章

  1. 终于等到你:CYQ.Data V5系列 (ORM数据层)最新版本开源了
  2. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类
  3. webapi - 模型验证
  4. 终端mysql Operation not permitted错误解决方案
  5. 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~
  6. [开发笔记]yum错误
  7. LINQ to SQL Where条件
  8. C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能
  9. 值得注意的ibatis动态sql语法格式
  10. Linux基础介绍【第三篇】