如何修复CA2202警告?

时间:2014-09-09 17:40:12

标签: c#

下面是我用来解析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;
    }

3 个答案:

答案 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。

更多信息:http://msdn.microsoft.com/en-us/library/ms182334.aspx

答案 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}}

(见http://msdn.microsoft.com/en-us/library/ms182334.aspx