And*_*ter 8 .net sgen xml-serialization
在.NET中构造XmlSerializer实例时,动态生成用于序列化和反序列化指定类型的程序集.这是一个耗时的过程.Microsoft的sgen.exe工具可用于预编译XmlSerializer实例,以便以后使用它们而无需动态生成它们.不幸的是,对于使用XmlAttributeOverrides的XmlSerializer实例,这是不可能的.
有没有办法预编译这些XmlSerializer实例以避免在运行时生成?
Andreas,这不是sgen工具本身的问题,这是由于XmlSerializer的实现.
当您创建XmlSerializer的实例时,使用仅具有一个Type参数的构造函数,它会检查缓存并查找预生成的程序集.但是当您使用带有XmlAttributeOverrides的构造函数时,XmlSerializer不会检查任何缓存并立即生成临时程序集.
最有可能的原因是,由于序列化逻辑中的相当激进的变化,您可以使用XmlAttributeOverrides参数来实现,这在sgen之类的工具中无法在编译时"预见".
如果你需要预编译的东西,你[叹气]必须避免使用XmlAttributeOverrides.如果无法做到这一点,请尝试提前创建所需的XmlSerializer实例,可能在后台线程中.
只是为了您的兴趣,这里是默认构造函数的代码(检查缓存并尝试查找预生成的程序集):
public XmlSerializer(Type type, string defaultNamespace)
{
this.events = new XmlDeserializationEvents();
if (type == null)
{
throw new ArgumentNullException("type");
}
this.mapping = GetKnownMapping(type, defaultNamespace);
if (this.mapping != null)
{
this.primitiveType = type;
}
else
{
this.tempAssembly = cache[defaultNamespace, type];
if (this.tempAssembly == null)
{
lock (cache)
{
this.tempAssembly = cache[defaultNamespace, type];
if (this.tempAssembly == null)
{
XmlSerializerImplementation implementation;
Assembly assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out implementation);
if (assembly == null)
{
this.mapping = new XmlReflectionImporter(defaultNamespace).ImportTypeMapping(type, null, defaultNamespace);
this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace);
}
else
{
this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace);
this.tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly, implementation);
}
}
cache.Add(defaultNamespace, type, this.tempAssembly);
}
}
if (this.mapping == null)
{
this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是与XmlAttributeOverrides一起使用的构造函数(总是生成序列化程序集):
public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace, string location, Evidence evidence)
{
this.events = new XmlDeserializationEvents();
if (type == null)
{
throw new ArgumentNullException("type");
}
XmlReflectionImporter importer = new XmlReflectionImporter(overrides, defaultNamespace);
for (int i = 0; i < extraTypes.Length; i++)
{
importer.IncludeType(extraTypes[i]);
}
this.mapping = importer.ImportTypeMapping(type, root, defaultNamespace);
if (location != null)
{
this.DemandForUserLocation();
}
this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3723 次 |
| 最近记录: |