日期:2014-05-17  浏览次数:20732 次

杯具的程序员,总是被这样的问题困扰:程序第一遍运行时运行到这一行代码就死机了——就于XML转换的问题。
抓狂的问题

我的程序要用到从XML反序列化成一个类的功能,用的就是系统自带的System.Xml.Serialization中的XmlSerializer。

一、症状

程序第一遍运行的时候,运行到
XmlSerializer serializer = new XmlSerializer(typeof(T));
这一行语句的时候就卡机。不论你等到多长时间,都不会往下运行了。但是,奇葩之一是,你只要按一个
Ctrl+ALT+DEL,程序就自动往下运行了。我总不能告诉用户,第一次运行出现死机的时候,你按一下
ctrl+alt+del组合键吧?

奇葩之二是,出现一次这样的症状之后,就没有这样的问题,再次调用此方法,非常顺畅。

奇葩之三是,一模一样的程序,以前从来没有出现过。难道是VS2008还有什么隐含的编译选项?

二、附源程序:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
namespace XYHIS
{
    class XMLSrlz
    {
        public static T DeXMLSerialize<T>(string xmlString)
        {
            T cloneObject = default(T);
            StringBuilder buffer = new StringBuilder();
            buffer.Append(xmlString);
            XmlSerializer serializer = new XmlSerializer(typeof(T));//这行程序
            using (TextReader reader = new StringReader(buffer.ToString()))
            {                
                Object obj = serializer.Deserialize(reader);               
                cloneObject = (T)obj;
            }
            return cloneObject;
        }
}


------解决方案--------------------
先把string放到sb
再把sb to到string
会快很多吗?


------解决方案--------------------
XmlSerializer serializer = new XmlSerializer(typeof(T));
序列化内部其实是生成一个动态程序集,然后通过它生成XmlTypeMapping来实现的
那个程序集仅在第一次new XmlSerializer(typeof(T))时生成,后面再调用会进行重用
在生成的时候,可能会由于对象过于复杂或者包含有UnknowType的成员,.net会用反射去查找导致过高的CPU和内存调度,最终“死机”。
猜测Ctrl+ALT+DEL的taskmgr.exe的线程优先级比一般程序要高,可以打断这种调度

在成员类型比较复杂时,可用XmlIncludeAttribute来指定成员的基类型