当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - How to avoid XmlSerializer failure if process environment is too large?

问题描述:

I ran into a strange problem last week. A call to new XMLSerializer(typeof(MyType)) crashed with an ExternalException, telling me that csc.exe could not be executed.

After some investigation I found that this exception only occurs if the process environment size reaches a "critical" limit. I created a little sample application to verify that reason.

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; }

}

}

}

If FillProcessEnvironmentBlock is called with parameter false, the critical size is not reached, if it's called with true, the ExternalException is thrown. I tested it on two different WindowsXP 32bit SP2 machines, with the same result.

I know that csc.exe is called to create a temporary assembly used to read/write the xml file. But I don't know why the call to csc.exe fails if the process environment is too large.

Does anyone know the reason for this exception? And how can I work around it (if I don't want to write my own xml serialization)? Are there any other known problems causeed by a process environment that's too large?

网友答案:

You can precompile serializers using Sgen tool or MSBuild Sgen task

分享给朋友:
您可能感兴趣的文章:
随机阅读: