首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CA2202,如何解决这种情况?

CA2202,如何解决这种情况?
EN

Stack Overflow用户
提问于 2010-09-30 22:41:12
回答 12查看 38K关注 0票数 102

谁能告诉我如何从下面的代码中删除所有的CA2202警告?

代码语言:javascript
复制
public static byte[] Encrypt(string data, byte[] key, byte[] iv)
{
    using(MemoryStream memoryStream = new MemoryStream())
    {
        using (DESCryptoServiceProvider cryptograph = new DESCryptoServiceProvider())
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                using(StreamWriter streamWriter = new StreamWriter(cryptoStream))
                {
                    streamWriter.Write(data);
                }
            }
        }
        return memoryStream.ToArray();
    }
}

警告7 CA2202 : Microsoft.Usage : Object 'cryptoStream‘可以在方法'CryptoServices.Encrypt(string,byte[],byte[])’中释放多次。若要避免生成字符串,不应在对象上多次调用Dispose。用法: Lines: 34 Warning 8 CA2202参数: Microsoft.Usage : Object 'memoryStream‘可以在方法'CryptoServices.Encrypt(string,byte[],byte[])’中多次释放。为避免生成线条,您不应在一个对象上多次调用Dispose。例如: System.ObjectDisposedException : 34,37

您需要Visual Studio Code Analysis才能看到这些警告(这些不是c#编译器警告)。

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2010-10-12 18:05:42

这将在没有警告的情况下编译:

代码语言:javascript
复制
    public static byte[] Encrypt(string data, byte[] key, byte[] iv)
    {
        MemoryStream memoryStream = null;
        DESCryptoServiceProvider cryptograph = null;
        CryptoStream cryptoStream = null;
        StreamWriter streamWriter = null;
        try
        {
            memoryStream = new MemoryStream();
            cryptograph = new DESCryptoServiceProvider();
            cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            var result = memoryStream;              
            memoryStream = null;
            streamWriter = new StreamWriter(cryptoStream);
            cryptoStream = null;
            streamWriter.Write(data);
            return result.ToArray();
        }
        finally
        {
            if (memoryStream != null)
                memoryStream.Dispose();
            if (cryptograph != null)
                cryptograph.Dispose();
            if (cryptoStream != null)
                cryptoStream.Dispose();
            if (streamWriter != null)
                streamWriter.Dispose();
        }
    }

编辑回应评论:我刚刚再次验证了这段代码没有生成警告,而原来的代码生成了警告。在原始代码中,CryptoStream.Dispose()MemoryStream().Dispose()实际上被调用了两次(这可能是问题,也可能不是问题)。

修改后的代码的工作方式如下:一旦将处置的责任转移到另一个对象,就将引用设置为null。例如,在调用CryptoStream构造函数成功后,将memoryStream设置为null。调用StreamWriter构造函数成功后,cryptoStream设置为null。如果没有发生异常,streamWriter将被放置在finally块中,并将依次释放CryptoStreamMemoryStream

票数 -4
EN

Stack Overflow用户

发布于 2010-10-01 21:07:12

在这种情况下,您应该禁止显示警告。处理一次性物品的代码应该是一致的,并且您不必关心其他类获取您创建的一次性物品的所有权,并对它们调用Dispose

代码语言:javascript
复制
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
public static byte[] Encrypt(string data, byte[] key, byte[] iv) {
  using (var memoryStream = new MemoryStream()) {
    using (var cryptograph = new DESCryptoServiceProvider())
    using (var cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
    using (var streamWriter = new StreamWriter(cryptoStream)) {
      streamWriter.Write(data);
    }
    return memoryStream.ToArray();
  }
}

更新:IDisposable.Dispose文档中,您可以阅读以下内容:

如果对象的Dispose方法被多次调用,则该对象必须忽略第一次之后的所有调用。如果对象的Dispose方法被多次调用,则不能引发异常。

可以争辩说,这条规则的存在是为了让开发人员可以在一系列可处理的组件中合理地使用using语句,就像我在上面展示的那样(或者这只是一个很好的副作用)。因此,出于同样的原因,CA2202没有任何有用的用途,应该在项目方面加以抑制。真正的罪魁祸首是Dispose的错误实现,CA1065应该注意这一点(如果这是您的责任)。

票数 143
EN

Stack Overflow用户

发布于 2010-09-30 23:09:53

好吧,这是准确的,这些流上的Dispose()方法将被多次调用。StreamReader类将获得cryptoStream的“所有权”,因此处理streamWriter也会处理cryptoStream。类似地,CryptoStream类接管memoryStream的责任。

这些并不是真正的bug,这些.NET类对于多个Dispose()调用是有弹性的。但是,如果您想摆脱警告,那么您应该删除这些对象的using语句。在推断如果代码抛出异常会发生什么的时候,你自己也会有点痛苦。或者使用属性关闭警告。或者忽略警告,因为它很愚蠢。

票数 40
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3831676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档