上周我遇到了一个奇怪的问题。打电话给
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序列化,我该如何解决这个问题呢?工艺环境过大是否会导致其他已知问题?