XmlSerializer内幕
在使用.NET的XmlSerializer时,.NET会在运行时编译出一个或多个专门用来解析序列化类型的临时程序集DLL. 编译和加载这个临时的程序集是非常耗时的一件事. 而且有时在Production环境下,没有编译器(csc.exe),还会发生错误.
“c6pyy1to”就是.NET动态编译出的程序集.
用Stopwatch测试,这一块用时2秒左右.
用sgen加速
为了解决这一问题,在.NET SDK中MS提供了一个工具sgen.exe, 用sgen我们可以在运行之前”预编译”这个动态生成的dll.
下面是sgen的说明和基本的用法:
Setting environment to use Microsoft .NET Framework v2.0 SDK tools.
For a list of SDK tools, see the 'StartTools.htm' file in the bin folder.
D:\Program Files\Microsoft Visual Studio 8\SDK\v2.0>sgen
Microsoft (R) Xml Serialization support utility
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserved.
Missing required command-line argument: The name of the source assembly.
Generates serialization assemblies for use with XmlSerializer.
The utility allows developers to pre-generate assemblies for serialization
and deploying the assemblies with the application.
Usage: sgen.exe [[/assembly:<assembly name>] | [<assembly file location>]]
[/type:] [/reference:] [/compiler:] [/debug] [/keep] [/nologo]
[/silent] [/verbose]
我们可以利用VS的post-build event将这个命令在VS编译后自动运行, 做法如下:
再次编译项目,sgen已经自动运行了.
为了检验sgen的效果,我们可以再次运行图二中的代码,这次这块代码只用了20多毫秒.
补充说明
- 我们不需要去手工引用并使用生成的*.XmlSerializer.DLL的。只要把它放在于程序目录里,.NET会自动在运行时加载. 加载失败时,按旧的方式动态生成并加载.
- 只有使用XmlSerializer的ctor(), ctor(Type), ctor(Type, string)这三个构造函数时,预编译出的DLL才有效果。而且对ctor(Type, string)的形式,第二个参数namespace必须和SGen所使用的namespace一致。对于其他构造函数,不但不能使用预生成的DLL,而且会每次构造时都重新生成一个新的DLL,即使构造参数完全相同。不知道是不是.NET的bug.
- 要注意SGen缺省会把所有可能序列化的类型都生成对应的xml序列化类.
- 项目属性的的Build选项卡有个”Generate serialization assembly”,但好像不起什么作用, 不知道是不是VS的bug.(听说项目中有web service的代理类时,会起作用,有空试试)