不要多次丢弃对象

时间:2014-05-13 16:36:23

标签: memory-management fxcop .net

似乎无法理解为什么FXCop抱怨我多次处理memoryStream对象。就像我所知道的那样,我只是在finally块中处理它。

完整的错误消息是:

CA2202不要多次处置对象对象'memoryStream'可以在方法'MessageTransform.GetEnvelope(Message)'中多次处理。为避免生成System.ObjectDisposedException,不应在对象上多次调用Dispose:Lines:48 Api MessageTransform.cs 48

        var memoryStream = new MemoryStream();
        try
        {
            var messageBuffer = message.CreateBufferedCopy(int.MaxValue);
            var xPathNavigator = messageBuffer.CreateNavigator();

            var xmlWriter = XmlWriter.Create(memoryStream);
            xPathNavigator.WriteSubtree(xmlWriter);
            xmlWriter.Flush();
            xmlWriter.Close();

            memoryStream.Position = 0;
            var xdoc = XDocument.Load(XmlReader.Create(memoryStream));
            return xdoc;
        }
        catch (ApplicationException e)
        {
            Console.WriteLine(e.Message);
            return null;
        }
        finally
        {
            memoryStream.Dispose();
        }

如果我在using块中包含相同的代码,我会得到同样的错误。

using (var memoryStream = new MemoryStream())
{
    var messageBuffer = message.CreateBufferedCopy(int.MaxValue);
    var xPathNavigator = messageBuffer.CreateNavigator();

    var xmlWriter = XmlWriter.Create(memoryStream);
    xPathNavigator.WriteSubtree(xmlWriter);
    xmlWriter.Flush();
    xmlWriter.Close();

    memoryStream.Position = 0;
    var xdoc = XDocument.Load(XmlReader.Create(memoryStream));
    return xdoc;
}

这只是一个过度活跃的FXCop的问题,还是使用using块或.Dispose()不知何故不适用于System.IO.MemoryStream?

2 个答案:

答案 0 :(得分:1)

XmlWriter可以从Close方法处理流,这是规则所采用的方法。但是,此行为是有条件的,不应以您描述的方式为流创建的XmlWriter中调用。

答案 1 :(得分:1)

正如Nicole所描述的那样,XmlWriters' Close可以处置Memorystream - 对象,这会导致错误被提升。

我想指出using语句和try-finally语句完全相同。编译器将使用语句转换为执行的tryblock和finallyblock中的Dispose()。