2012-02-20 81 views
3

如何摆脱CA2202警告(CA2202:Microsoft.Usage:Object'compressedStream'可以在方法'Compression.InternalDecompress(byte [])'中多次抛弃。为避免生成System.ObjectDisposedException你不应该调用从下面的代码处置的对象上一次以上):摆脱CA2202

 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 /终于模式取代它,但后来我的获取CA2000(CA2000:Microsoft.Reliability:在'Compression.InternalDecompress(byte [])'方法中,在对所有引用超出范围之前调用System.IDisposable.Dispose对象的'stream')。我曾尝试更换这样上面的代码:

 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(); 
      } 
     } 
+0

可能重复(http://stackoverflow.com/questions/3831676/ca2202-how-to-solve-this-case) – 2012-02-20 17:22:48

回答

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 warning disable 2202 

namespace Your.Namespace 
{ 
... 
} 

#pragma warning restore 2202 
+0

不幸的是,上面的代码也得到了警告:“方法'Compression.InternalDecompress(byte [])'中可以多次放置CA2202:Microsoft.Usage:Object'ms'。为避免生成System.ObjectDisposedException,您应该不要在对象上放置多次。“ – Ambuj 2012-02-21 08:54:01

+1

既然这只是一个警告,也许添加一个杂注,看不到警告会做。请参阅上面的修改代码 – 2012-02-21 12:44:30

+0

这对我来说很烦人,2016年这些警告(特别是CA2202)似乎完全是虚假的,并且几乎标记了所有USING语句,但实际上并未表示可能发生的事件。 – 2016-03-15 17:42:18

1

这是我结束了什么 - 摆脱了CA2000和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(); 
    } 
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; 
    } 
[CA2202,如何解决这种情况下]的