【发布时间】:2012-01-25 07:29:16
【问题描述】:
我正在使用下面的代码来获取一个 xml 字符串。
public static string ToXMLString(object obj, string nodeName)
{
XmlSerializer xmlSerializer = default(XmlSerializer);
string xml = string.Empty;
StreamReader r = default(StreamReader);
try
{
if (obj != null)
{
using (MemoryStream m = new MemoryStream())
{
using (XmlWriter writer = XmlWriter.Create(m, new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true }))
{
// Don't include XML namespace
XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
xmlnsEmpty.Add("", "");
if (xmlSerializer == null)
xmlSerializer = new XmlSerializer(obj.GetType(), new XmlRootAttribute(nodeName));
xmlSerializer.Serialize(writer, obj, xmlnsEmpty);
m.Flush();
m.Position = 0;
r = new StreamReader(m);
xml = r.ReadToEnd();
xmlSerializer = null;
}
}
}
return xml;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
finally
{
r.Close();
r.Dispose();
}
//XmlSerializer xmlSerializer;
}
我有一个使用该方法运行的循环,一段时间后我得到一个内存不足异常,如下所示:
异常的原因可能是什么? using 语句真的在处理流吗?或者我可以使用其他什么替代方法?
【问题讨论】:
-
它不会影响代码,但是在顶部声明这些变量没有好处,也没有在最后将
xmlSerializer分配给null;我只是在线声明,即var xmlSerializer = new XmlSerializer(...);。你没有处理读者,但这不会杀死你。实际上,如果您只想要字符串,您可以写信给StringBuilder- 避免弄乱Stream... -
我们可以看到您正在序列化的对象模型吗?我怀疑这与模型有关 - 类似于循环引用(即逃避内置检测 - 并非不可能),或类似的东西
-
using在退出 using 块时调用IDisposable.Dispose()。所以你的那部分代码没问题。 -
这与OOM错误无关,但是:这是相同代码的稍微重构和更直接的版本:pastie.org/3248365
-
想知道你为什么在这里两次使用
default(StreamReader)语法?此外,您正在覆盖r而不处置先前的实例。无论如何它都会超出范围并被 GC 处理,但不会像显式处理那样快。