代码之家  ›  专栏  ›  技术社区  ›  Marco Spatz

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

  •  0
  • Marco Spatz  · 技术社区  · 16 年前

    上周我遇到了一个奇怪的问题。打电话给 new XMLSerializer(typeof(MyType)) 由于外部异常而崩溃,告诉我无法执行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; }
            }
        }
    }
    

    如果 FillProcessEnvironmentBlock 使用参数false调用,未达到临界大小,如果使用true调用,则引发ExternalException。我在两台不同的WindowsXP 32位SP2计算机上测试了它,得到了相同的结果。

    有人知道这个例外的原因吗?如果我不想编写自己的xml序列化,我该如何解决这个问题呢?工艺环境过大是否会导致其他已知问题?

    1 回复  |  直到 16 年前
        1
  •  1
  •   desco    16 年前

    可以使用 Sgen Sgen task

    推荐文章