7

我有两个项目的解决方案;一个 asp.net MVC 应用程序和一个类库。我们称它们为项目 MVC 和项目 CLS。

在 CLS 项目中,有两个不同版本的 XSD 文件(V1 和 V2),我使用xsd2code创建了两个同名但在不同命名空间(V1 和 V2)下的可序列化类。

在 MVC 项目中,当用户上传一个 XML 文件时,CLS.dll用于将 XML 反序列化为一个对象。当XML文件是V1类型时,反序列化非常快,但是V2版本的XSD文件要复杂很多,反序列化可能需要几分钟,只有第一次(之后非常快) ,直到应用程序再次运行)。

我使用Sgen.exe工具CLS.XmlSerializers.dll为 CLS.V2 类型创建了一个序列化程序程序集 ( ),以消除第一次即时创建程序集,从而提高性能。

我已经成功地将 Sgen 任务添加到 Post Build 事件中,并且CLS.XmlSerializers.dll每次构建项目时都会创建程序集。此外,我在这篇文章中使用了单元测试代码来确保程序集已加载,并且确实如此。测试成功通过。

但是,第一次反序列化 XML 文件仍然需要很长时间。所以,还是应该有问题。但是,我不知道是什么。请帮忙。

更新:

Fuslogvw.exe按照评论中的建议使用了,我可以看到CLS.XmlSerializers.dll正在成功加载。那么,为什么第一次反序列化 XML 文件大约需要一分钟,但之后每次都不到一秒?

更新 2:

两个 XSD 文件之间的区别之一是第二个 (V2) 引用了一个非常大的 XSD 文件,该文件包含xs:enumeration在主文件中使用的某些类型的定义。而且,这就是反序列化需要很长时间的原因。由于我需要做的就是将 XML 文件反序列化为对象,并且不需要针对这些枚举验证属性和元素的值,因此我最终删除了对该 XSD 文件的引用,并将所有枚举类型替换为它们的基本类型(在本例中为xs:string)。现在,V2 的反序列化速度和 V1 一样快,我什至不需要使用Sgen.exe. 我想Sgen.exe只有在需要反序列化非常大的 XML 文件的情况下才有帮助。在我的例子中,XML 文件总是非常小,但是反序列化是(曾经)复杂的。

4

2 回答 2

4

为了提高 XML 序列化的性能,每次为特定类型首次实例化 XmlSerializer 时都会动态生成程序集。它在应用程序生命周期中只发生一次,但这使得它的第一次使用很慢。

当您实例化 XmlSerializer 时,您必须传递您将尝试使用该序列化程序实例进行序列化和反序列化的对象的类型。序列化程序检查 Type 的所有公共字段和属性,以了解实例在运行时引用的类型。然后,它继续为一组类创建 C# 代码,以使用 System.CodeDOM 命名空间中的类处理序列化和反序列化。在此过程中,XmlSerializer 检查 XML 序列化属性的反射类型,以根据 XML 格式定义自定义创建的类。然后将这些类编译成一个临时程序集,并由 Serialize() 和 Deserialize() 方法调用以执行 XML 到对象的转换。

完整内容:使用 XmlSerializer 解决常见问题

更多信息:XmlSerializer 构造函数性能问题

于 2017-09-03T17:58:47.963 回答
1

这是 x64 jit 编译器的一个已知问题,在某些情况下可能会非常慢。这就是为什么在代码已经编译后第二次运行反序列化时性能要好得多的原因。

尝试使用 .net 4.6 或更高版本,它具有新版本的 x64 jit 编译器 (RyuJIT)。如果无法更新 .net 版本,请查看此线程

于 2017-08-28T23:39:27.480 回答