下面是我用来解析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;
}发布于 2014-09-09 17:46:16
获得此警告的原因是,XmlTextWriter.Dispose()将确保也释放位于MemoryStream下面的对象。因此,当using的MemoryStream作用域结束时,它将尝试释放MemoryStream对象,从而发出警告。
using块编译成try-finally块。代码中的内部using块将调用writer上的Dispose。它将在您的MemoryStream对象mStream上调用mStream。在从内部使用块退出控制时,外部使用块将尝试释放对象writer,但由于它已经被释放,您将在代码分析工具上得到警告。
为了消除警告,您可以删除第一个using语句并使用一个try-finally块。但是,当您输入第二个mStream语句时,请记住将设置为 using。这已经在CA2202:不要多次释放对象上解释过了。
您的代码看起来应该是:
public static String PrintXML(String XML)
{
String result = "";
string[] xmlSeperators = new string[] { "<?" };
string[] splitResults = new string[2];
if (!String.IsNullOrEmpty(XML))
{
MemoryStream mStream = null;
try
{
mStream = new MemoryStream();
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
mStream = null; // important
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 = System.Xml.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;
}
}
}
finally
{
if (mStream != null)
{
mStream.Dispose();
}
}
}
return result;
}发布于 2014-09-09 17:44:34
正如另一个答案所指出的,您可以取消错误警告,但是要消除这个问题,实际上只能在代码中调用.Dispose()方法一次,并且只在处理完它之后。如果再次释放已释放对象,则会引发System.ObjectDisposedException异常,但尚不确定。可以多次对对象调用正确的dispose方法,并且将/可能不会为您生成错误。但不能保证这么做。
微软的开发人员网络文档中已经说明了解决这个问题的方法,
若要修复违反此规则的问题,请更改实现,以便无论代码路径如何,只对对象调用一次Dispose。
欲了解更多信息:http://msdn.microsoft.com/en-us/library/ms182334.aspx
发布于 2014-09-09 17:45:21
当嵌套的using语句中,内部语句包含外部语句中的资源时,就会发生这种情况。在这种情况下,XmlTextWriter将在MemoryStream被释放时释放它,然后外部using语句将使其第二次被释放。
通过用try/ using替换外部using语句,您可以手动释放using:
MemoryStream mStream = null;
try
{
mStream = new MemoryStream();
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
mStream = null;
...
}
}
finally
{
if(mStream != null)
mStream.Dispose();
}(见http://msdn.microsoft.com/en-us/library/ms182334.aspx)
https://stackoverflow.com/questions/25750753
复制相似问题