Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MemoryStream, XmlTextWriter and Warning 4 CA2202 : Microsoft.Usage

Tags:

c#

xml

linq

dispose

The Run Code Analysis command in Visual Studio 2010 Ultimate returns a warning when seeing a certain pattern with MemoryStream and XmlTextWriter.

This is the warning:

Warning 7 CA2202 : Microsoft.Usage : Object 'ms' can be disposed more than once in method 'KinteWritePages.GetXPathDocument(DbConnection)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 421 C:\Visual Studio 2010\Projects\Songhay.DataAccess.KinteWritePages\KinteWritePages.cs 421 Songhay.DataAccess.KinteWritePages

This is the form:

static XPathDocument GetXPathDocument(DbConnection connection)
{
    XPathDocument xpDoc = null;
    var ms = new MemoryStream();
    try
    {
        using(XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8))
        {
            using(DbDataReader reader = CommonReader.GetReader(connection, Resources.KinteRssSql))
            {

                writer.WriteStartDocument();
                writer.WriteStartElement("data");

                do
                {
                    while(reader.Read())
                    {
                        writer.WriteStartElement("item");
                        for(int i = 0; i < reader.FieldCount; i++)
                        {
                            writer.WriteRaw(String.Format("<{0}>{1}</{0}>", reader.GetName(i), reader[i].ToString()));
                        }
                        writer.WriteFullEndElement();
                    }

                } while(reader.NextResult());

                writer.WriteFullEndElement();
                writer.WriteEndDocument();

                writer.Flush();
                ms.Position = 0;

                xpDoc = new XPathDocument(ms);
            }
        }

    }
    finally
    {
        ms.Dispose();
    }

    return xpDoc;
}

The same kind of warning is produced for this form:

XPathDocument xpDoc = null;
using(var ms = new MemoryStream())
{
    using(XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8))
    {
        using(DbDataReader reader = CommonReader.GetReader(connection, Resources.KinteRssSql))
        {
            //...
        }
    }

}

return xpDoc;

By the way, the following form produces another warning:

XPathDocument xpDoc = null;
var ms = new MemoryStream();
using(XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8))
{
    using(DbDataReader reader = CommonReader.GetReader(connection, Resources.KinteRssSql))
    {
        //...
    }
}

return xpDoc;

The above produces the warning:

Warning 7 CA2000 : Microsoft.Reliability : In method 'KinteWritePages.GetXPathDocument(DbConnection)', object 'ms' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'ms' before all references to it are out of scope. C:\Visual Studio 2010\Projects\Songhay.DataAccess.KinteWritePages\KinteWritePages.cs 383 Songhay.DataAccess.KinteWritePages

In addition to the following, what are my options?:

  • Supress warning CA2202.
  • Supress warning CA2000 and hope that Microsoft is disposing of MemoryStream (because Reflector is not showing me the source code).
  • Rewrite my legacy code to recognize the wonderful XDocument and LINQ to XML.
like image 553
rasx Avatar asked Mar 15 '26 10:03

rasx


1 Answers

First of all, you should never use new XmlTextWriter(). It has been deprecated since .NET 2.0. Use XmlWriter.Create() instead.

Secondly, the assignment to ms should be in a using block:

using (var ms = new MemoryStream())
{
    using (var writer = XmlWriter.Create(ms))
    {
        // ...
    }
}

I believe that the warning is correct. The MemoryStream could be disposed when the XmlTextWriter is disposed, then again in the "finally" block.

like image 87
John Saunders Avatar answered Mar 16 '26 23:03

John Saunders



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!