簡體   English   中英

如何修復CA2202警告?

[英]How do I fix the CA2202 warning?

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

獲得此警告的原因是XmlTextWriter.Dispose()將確保處理下面的MemoryStream對象。 因此,當MemoryStreamusing范圍結束時,它將嘗試處理MemoryStream對象,從而處理警告。

using塊編譯成try-finally塊。 內部using在你的代碼塊將調用Dispose在你的writer 這將在您的MemoryStream對象mStream上調用Dispose 在內部使用塊的控制出口處,外部使用塊將嘗試處理對象writer ,但由於它已經被處理,因此您將收到代碼分析工具的警告。

要刪除警告,可以刪除第一個using語句並使用try-finally塊。 但是請記住在輸入第二個using語句后立即mStream設置為null 這已在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;
}

您可以像其他答案所說的那樣抑制錯誤警告,但實際上只有在您完成代碼之后才能解決此問題以實際調用.Dispose()方法一次。 如果再次處理它,則處置的對象會引發System.ObjectDisposedException異常,但不確定。 可以在對象上多次調用正確的dispose方法,並且/可能不會為您生成錯誤。 但不保證這樣做。

Microsoft的開發者網絡文檔已經說明了對此的修復,

要修復違反此規則的行為,請更改實現,以便無論代碼路徑如何,都只為該對象調用一次Dispose。

有關更多信息,請訪問: http//msdn.microsoft.com/en-us/library/ms182334.aspx

當嵌套using語句時,會發生這種情況,其中inner語句包含來自outer語句的資源。 在這種情況下, XmlTextWriter將在處理MemoryStream時處置它,然后外部using語句將導致它第二次處理。

您可以通過using try / finally替換外部using語句來手動釋放MemoryStream:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM