首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复CA2202警告?

如何修复CA2202警告?
EN

Stack Overflow用户
提问于 2014-09-09 17:40:11
回答 3查看 1.6K关注 0票数 3

下面是我用来解析XML的方法。它在代码分析上给出了CA2202警告,它说可以多次释放对象mStream,而我不应该调用dispose超过一次。我该怎么解决这个警告呢?

代码语言:javascript
复制
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;
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-09 17:46:16

获得此警告的原因是,XmlTextWriter.Dispose()将确保也释放位于MemoryStream下面的对象。因此,当usingMemoryStream作用域结束时,它将尝试释放MemoryStream对象,从而发出警告。

using块编译成try-finally块。代码中的内部using块将调用writer上的Dispose。它将在您的MemoryStream对象mStream上调用mStream。在从内部使用块退出控制时,外部使用块将尝试释放对象writer,但由于它已经被释放,您将在代码分析工具上得到警告。

为了消除警告,您可以删除第一个using语句并使用一个try-finally块。但是,当您输入第二个mStream语句时,请记住将设置为 using。这已经在CA2202:不要多次释放对象上解释过了。

您的代码看起来应该是:

代码语言:javascript
复制
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;
}
票数 3
EN

Stack Overflow用户

发布于 2014-09-09 17:44:34

正如另一个答案所指出的,您可以取消错误警告,但是要消除这个问题,实际上只能在代码中调用.Dispose()方法一次,并且只在处理完它之后。如果再次释放已释放对象,则会引发System.ObjectDisposedException异常,但尚不确定。可以多次对对象调用正确的dispose方法,并且将/可能不会为您生成错误。但不能保证这么做。

微软的开发人员网络文档中已经说明了解决这个问题的方法,

若要修复违反此规则的问题,请更改实现,以便无论代码路径如何,只对对象调用一次Dispose。

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

票数 1
EN

Stack Overflow用户

发布于 2014-09-09 17:45:21

当嵌套的using语句中,内部语句包含外部语句中的资源时,就会发生这种情况。在这种情况下,XmlTextWriter将在MemoryStream被释放时释放它,然后外部using语句将使其第二次被释放。

通过用try/ using替换外部using语句,您可以手动释放using

代码语言:javascript
复制
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)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25750753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档