下面是我用来解析XML的方法。它在代码分析上给出了CA2202警告,该代码分析说对象mStream可以被多次处理,我不应该多次调用dispose。我该如何解决这个警告?
public static String PrintXML(String XML)
{
String result = "";
string[] xmlSeperators = new string[] { "<?" };
string[] splitResults = new string[2];
if (!String.IsNullOrEmpty(XML))
{
using (MemoryStream mStream = new MemoryStream())
{
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
XmlDocument document = new XmlDocument();
try
{
// Load the XmlDocument with the XML.
//Check if it is only XML
if (XML.StartsWith("<?"))
{
document.LoadXml(XML);
}
else
{
//Split the string appended before XML
splitResults = XML.Split(xmlSeperators, 2, StringSplitOptions.None);
if (splitResults.Length > 1)
{
string d = "<?" + splitResults[1];
document.LoadXml(d);
}
}
writer.Formatting = Formatting.Indented;
// Write the XML into a formatting XmlTextWriter
document.WriteContentTo(writer);
//xx.WriteTo(writer);
writer.Flush();
mStream.Flush();
// Have to rewind the MemoryStream in order to read its contents.
mStream.Position = 0;
// Read MemoryStream contents into a StreamReader.
StreamReader sReader = new StreamReader(mStream);
// Extract the text from the StreamReader.
String FormattedXML = sReader.ReadToEnd();
if (splitResults[0] != null)
{
result = splitResults[0] + "\n" + FormattedXML;
}
else
{
result = FormattedXML;
}
}
catch (XmlException xe)
{
Log.Error(xe);
throw;
}
}
}
}
return result;
}
答案 0 :(得分:3)
获得此警告的原因是XmlTextWriter.Dispose()
将确保处置不足的MemoryStream
对象。因此,当using
的{{1}}范围结束时,它会尝试处理MemoryStream
对象,从而处理警告。
MemoryStream
块编译成using
块。代码中的内部try-finally
阻止会在using
上调用Dispose
。这会在writer
对象Dispose
上调用MemoryStream
。在内部使用块的控制退出处,外部使用块将尝试处理对象mStream
,但由于它已经被处置,因此您将在代码分析工具上收到警告。
要删除警告,您可以删除第一个writer
语句并使用using
块。 但请记得在输入第二个try-finally
语句后立即将mStream
设置为null
。这已在CA2202: Do not dispose objects multiple times
您的代码如下:
using
答案 1 :(得分:0)
你可以像其他答案所说的那样抑制错误警告,但实际上只有在你的代码完成后才能解决这个问题才能实际调用.Dispose()
方法一次。如果再次处理它,则处置的对象会引发System.ObjectDisposedException异常,但不确定。可以在对象上多次调用正确的dispose方法,并且/可能不会为您生成错误。但不保证这样做。
微软的开发者网络文档
已经说明了对此的修复要修复违反此规则的行为,请更改实现,以便无论代码路径如何,都只为该对象调用一次Dispose。
答案 2 :(得分:0)
当你有内部语句包含来自外部语句的资源的嵌套using
语句时会发生这种情况。在这种情况下,XmlTextWriter
会在处置MemoryStream
时处置using
,然后外部using
语句将导致它被再次处置。
您可以通过try / finally替换外部MemoryStream mStream = null;
try
{
mStream = new MemoryStream();
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
mStream = null;
...
}
}
finally
{
if(mStream != null)
mStream.Dispose();
}
语句来手动释放MemoryStream:
{{1}}