3

如何摆脱 CA2202 警告(CA2202:Microsoft.Usage:对象“compressedStream”可以在方法“Compression.InternalDecompress(byte[])”中多次处理。为避免生成 System.ObjectDisposedException,您不应调用从以下代码中对一个对象进行多次处理):

        using (var compressedStream = new MemoryStream(inputData))
        using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
        using (var resultStream = new MemoryStream())
        {
            zipStream.CopyTo(resultStream);
            return resultStream.ToArray();
        }

我已经尝试摆脱“使用”语句并用 try/finally 模式替换它,但后来我得到 CA2000 (CA2000: Microsoft.Reliability: In method 'Compression.InternalDecompress(byte[])', call System.IDisposable.Dispose在所有对它的引用都超出范围之前在对象“流”上)。我试过像这样替换上面的代码:

        MemoryStream decompressedData = null;
        MemoryStream stream = null;
        GZipStream decompressor = null;
        try
        {
            decompressedData = new MemoryStream();
            stream = new MemoryStream(inputData);
            decompressor = new GZipStream(stream, CompressionMode.Decompress, false);
            stream = null;

            int bytesRead = 1;
            int chunkSize = 4096;
            byte[] chunk = new byte[chunkSize];

            while ((bytesRead = decompressor.Read(chunk, 0, chunkSize)) > 0)
            {
                decompressedData.Write(chunk, 0, bytesRead);
            }

            decompressor = null;

            return decompressedData.ToArray();
        }
        finally
        {
            if (stream != null)
            {
                stream.Dispose();
            }

            if (decompressor != null)
            {
                decompressor.Dispose();
            }

            if (decompressedData != null)
            {
                decompressedData.Dispose();
            }
        }
4

3 回答 3

1

This is what I ended up using - gets rid of both CA2000 and CA2202:

    private static MemoryStream GetMemoryStream()
    {
        return new MemoryStream();
    }

    private static byte[] InternalDecompress(byte[] inputData)
    {
        Debug.Assert(inputData != null, "inputData cannot be null");

        MemoryStream decompressedData = GetMemoryStream();
        MemoryStream inputDataMemoryStream = GetMemoryStream();

        GZipStream decompressor = null;

        try
        {
            inputDataMemoryStream.Write(inputData, 0, inputData.Length);
            inputDataMemoryStream.Position = 0;

            decompressor = new GZipStream(inputDataMemoryStream, CompressionMode.Decompress, false);

            int bytesRead;
            int chunkSize = 4096;
            byte[] chunk = new byte[chunkSize];

            while ((bytesRead = decompressor.Read(chunk, 0, chunkSize)) > 0)
            {
                decompressedData.Write(chunk, 0, bytesRead);
            }
        }
        finally
        {
            if (decompressor != null)
            {
                decompressor.Dispose();
            }
        }

        return decompressedData.ToArray();
    }
于 2012-02-21T13:02:28.583 回答
1

这就是我使用的:

public class Compression
{
    public Compression()
    {

    }

    public byte[] Compress(byte[] buffer)
    {
        byte[] gzBuffer;

        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
            {
                zip.Write(buffer, 0, buffer.Length);
                zip.Close();
            }
            ms.Position = 0;

            MemoryStream outStream = new MemoryStream();

            byte[] compressed = new byte[ms.Length];
            ms.Read(compressed, 0, compressed.Length);

            gzBuffer = new byte[compressed.Length + 4];
            Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
            Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
        }

        return gzBuffer;
    }

    public byte[] Decompress(byte[] gzBuffer)
    {
        byte[] buffer;

        using (MemoryStream ms = new MemoryStream())
        {
            int msgLength = BitConverter.ToInt32(gzBuffer, 0);
            ms.Write(gzBuffer, 4, gzBuffer.Length - 4);

            buffer = new byte[msgLength];

            ms.Position = 0;
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
            {
                zip.Read(buffer, 0, buffer.Length);
            }
        }

        return buffer;
    }
}

或者你可以在你的类中添加一个 pragma 语句

#pragma warning disable 2202

namespace Your.Namespace
{
...
}

#pragma warning restore 2202
于 2012-02-20T17:31:12.367 回答
0

这是我的尝试。它有效并且避免了 CA2202

    /// <summary>
    /// Compresses byte array to new byte array.
    /// </summary>
    public byte[] Compress(byte[] raw)
    {
        MemoryStream outStream = null;
        GZipStream tinyStream = null;
        byte[] retValue = null;
        try
        {
            outStream = new MemoryStream();
            tinyStream = new GZipStream(outStream, CompressionMode.Compress);
            using (var mStream = new MemoryStream(raw))
                mStream.CopyTo(tinyStream);
        }
        finally
        {
            if (tinyStream != null)
            {
                tinyStream.Dispose();
                retValue = outStream.ToArray();
            }
            else if (outStream != null)
            {
                retValue = outStream.ToArray();
                outStream.Dispose();
            }
        }
        return retValue;
    }
于 2016-04-15T16:06:26.807 回答