【问题标题】:CA2202: Object can be disposed of more than onceCA2202:对象可以被多次处理
【发布时间】:2019-04-29 15:54:15
【问题描述】:

我在以下代码 sn-p 中收到以下警告,但我不明白为什么

警告 CA2202:Microsoft.Usage:对象“memStream”可以在方法“Encrypt(string)”中多次处理。为避免生成 System.ObjectDisposedException,您不应在一个对象上多次调用 Dispose。

代码:

string Encrypt(string toEncrypt)
{
    byte[] key = ...
    byte[] iv = ...

    using (AesCng aes = new AesCng())
    using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
    using (MemoryStream memStream = new MemoryStream())
    using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
    {
        UTF7Encoding encoder = new UTF7Encoding();
        byte[] bytes = encoder.GetBytes(toEncrypt);

        cryptoStream.Write(bytes, 0, bytes.Length);
        cryptoStream.FlushFinalBlock();

        return Convert.ToBase64String(memStream.ToArray());
    }
}

据我所知,CryptoStream 对象在处置时不会处置传入的 Stream。那么变量memStream怎么可能被多次释放呢?

非常感谢。

【问题讨论】:

标签: c# cng


【解决方案1】:

您可以使用带有 leaveOpen 参数的重载 CryptoStream 构造函数。

不需要这个,因为 CryptoStream 对象在使用块

cryptoStream.FlushFinalBlock();

代码:

string Encrypt(string toEncrypt)
{
    byte[] key = ...
    byte[] iv = ...

    using (AesCng aes = new AesCng())
    using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
    using (MemoryStream memStream = new MemoryStream())
    using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write,true))
    {
        UTF7Encoding encoder = new UTF7Encoding();
        byte[] bytes = encoder.GetBytes(toEncrypt);

        cryptoStream.Write(bytes, 0, bytes.Length);

        return Convert.ToBase64String(memStream.ToArray());
    }
}

leaveOpen: true 表示在处理 CryptoStream 对象时不关闭底层流

CryptoStream ctor

【讨论】:

  • 还可以考虑删除FlushFinalBlock 并将return 移到using 块之外(以使代码更简洁)。
  • 您可能想再次阅读我的评论。尤其是句子的第二部分。
【解决方案2】:

CryptoStream.Dispose() 默认情况下会处理底层流。如果您不希望出现这种行为,则需要使用构造函数 overload,该构造函数显式使基础流在处置 CryptoStream 时保持打开状态。

您可以看到它是如何实现的here

【讨论】:

  • 啊,谢谢...我调查了一下,没有意识到 Close 相当于 Dispose 用于流
  • 我假设您的意思是链接到docs.microsoft.com/en-us/dotnet/api/… 而不是Dispose?我怀疑你原来的建议不会编译。
猜你喜欢
  • 2014-04-10
  • 2011-04-28
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多