如果进程环境太大,如何避免XmlSerializer失败?

时间:2010-08-02 08:01:09

标签: c# .net xml process

上周我遇到了一个奇怪的问题。对new XMLSerializer(typeof(MyType))的调用因ExternalException而崩溃,告诉我无法执行csc.exe。 经过一些调查后,我发现只有在进程环境大小达到“关键”限制时才会发生此异常。我创建了一个小样本应用程序来验证原因。

namespace EnvironmentTester
{
    public class Program
    {
        private static void Main(string[] args)
        {
            FillProcessEnvironmentBlock(false);
            SerializeDataObject();
        }

        private static void SerializeDataObject()
        {
            var dto = new DataObject {Name = "MyDto"};

            try
            {
                var xmlSerializer = new XmlSerializer(dto.GetType()); // throws exception
                xmlSerializer.Serialize(TextWriter.Null, dto);

                Console.WriteLine("No exception occured.");
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception occured : " + e.GetType());
            }

            Console.ReadKey();
        }

        private static void FillProcessEnvironmentBlock(bool fillToMax)
        {
            var currentEnvVarIndex = 0;
            var environmentSize = GetEnvironmentSize();

            int criticalEnvironmentSize = fillToMax ? 30692 : 30691;

            while (environmentSize < criticalEnvironmentSize)
            {
                var envVarName = "Env" + currentEnvVarIndex;
                var envVarValueLength = (criticalEnvironmentSize - environmentSize - envVarName.Length - 2) % 32000;
                Environment.SetEnvironmentVariable(envVarName, new string('a', envVarValueLength));
                currentEnvVarIndex++;
                environmentSize = GetEnvironmentSize();
            }
        }

        private static int GetEnvironmentSize()
        {
            var envVars = Environment.GetEnvironmentVariables();
            int environmentSize = 0;


            foreach (string envKey in envVars.Keys)
            {
                environmentSize += envKey.Length;
            }

            foreach (string envVar in envVars.Values)
            {
                environmentSize += envVar.Length;
            }

            environmentSize += 2*envVars.Keys.Count; // add the '=' and the '\0'

            return environmentSize;
        }

        public class DataObject
        {
            [XmlAttribute("ObjectName")]
            public string Name { get; set; }
        }
    }
}

如果使用参数false调用FillProcessEnvironmentBlock,则不会达到临界大小,如果使用true调用,则抛出ExternalException。我在两台不同的WindowsXP 32位SP2机器上测试了它,结果相同。

我知道调用csc.exe来创建用于读/写xml文件的临时程序集。但是我不知道为什么如果进程环境太大,对csc.exe的调用就会失败。

有谁知道这个例外的原因?我该如何解决它(如果我不想编写自己的xml序列化)?过程环境过大会导致其他已知问题吗?

1 个答案:

答案 0 :(得分:1)

您可以使用Sgen工具或MSBuild Sgen task

预编译序列化程序