Dou*_*ugc 18 .net c# xml performance xml-serialization
我目前有一个非常奇怪的问题,我似乎无法弄清楚如何解决它.
我有一个相当复杂的类型,我正在尝试使用XmlSerializer类进行序列化.这实际上运行正常,类型序列化正确,但似乎需要很长时间这样做; 大约5秒钟,具体取决于对象中的数据.
经过一些分析后,我已经缩小了问题 - 奇怪的是 - 在调用XmlSerializer.Serialize时指定一个XmlRootAttribute.我这样做是为了将从ArrayOf序列化的集合的名称更改为更有意义的东西.一旦我删除参数,操作几乎是即时的!
任何想法或建议都会非常好,因为我完全被这个问题所困扰!
Dou*_*ugc 25
只是遇到这个问题的其他人; 有了上面的答案和MSDN中的示例我设法使用以下类解决此问题:
public static class XmlSerializerCache
{
private static readonly Dictionary<string, XmlSerializer> cache =
new Dictionary<string, XmlSerializer>();
public static XmlSerializer Create(Type type, XmlRootAttribute root)
{
var key = String.Format(
CultureInfo.InvariantCulture,
"{0}:{1}",
type,
root.ElementName);
if (!cache.ContainsKey(key))
{
cache.Add(key, new XmlSerializer(type, root));
}
return cache[key];
}
}
Run Code Online (Sandbox Code Playgroud)
然后,而不是使用默认的XmlSerializer构造函数,它采用XmlRootAttribute,我使用以下代码:
var xmlRootAttribute = new XmlRootAttribute("ExampleElement");
var serializer = XmlSerializerCache.Create(target.GetType(), xmlRootAttribute);
Run Code Online (Sandbox Code Playgroud)
我的应用程序现在再次执行!
Jef*_*nal 19
正如对原始问题的后续评论中所提到的,.NET在创建XmlSerializers时会发出程序集,如果使用以下两个构造函数之一创建生成的程序集,则会缓存生成的程序集:
XmlSerializer(Type)
XmlSerializer(Type, String)
Run Code Online (Sandbox Code Playgroud)
使用其他构造函数生成的程序集不会被缓存,因此.NET每次都必须生成新的程序集.
为什么?这个答案可能并不十分令人满意,但是在Reflector中对此进行了解,您可以看到用于存储和访问生成的XmlSerializer程序集(TempAssemblyCacheKey)的键只是一个简单的复合键,它是从可序列化类型和(可选)其命名空间构建的.
因此,没有机制来判断缓存XmlSerializer是否SomeType具有特殊XmlRootAttribute或默认缓存.
很难想到密钥无法容纳更多元素的技术原因,所以这可能只是一个没有人有时间实现的功能(特别是因为它涉及改变其他稳定的类).
您可能已经看过这个,但是如果没有,那么XmlSerializer类文档讨论了一种解决方法:
如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且永远不会卸载,这会导致内存泄漏和性能下降.最简单的解决方案是使用前面提到的两个构造函数之一.否则,必须将程序集缓存在a中
Hashtable,,如以下示例所示.
(我在这里省略了这个例子)