Как избежать сбоя XmlSerializer, если среда процесса слишком велика? - PullRequest
0 голосов
/ 02 августа 2010

Я столкнулся со странной проблемой на прошлой неделе.Вызван 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; }
        }
    }
}

Если FillProcessEnvironmentBlock вызывается с параметром false, критический размер не достигается, если вызывается с true, вызывается ExternalException.Я тестировал его на двух разных машинах WindowsXP 32bit SP2 с одинаковым результатом.

Я знаю, что csc.exe вызывается для создания временной сборки, используемой для чтения / записи XML-файла.Но я не знаю, почему происходит сбой вызова csc.exe, если среда процесса слишком велика.

Кто-нибудь знает причину этого исключения?И как я могу обойти это (если я не хочу писать свою собственную сериализацию XML)?Существуют ли другие известные проблемы, вызванные слишком большой средой процесса?

1 Ответ

1 голос
/ 02 августа 2010

Вы можете предварительно скомпилировать сериализаторы, используя инструмент Sgen или MSBuild Sgen task

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...