代码之家  ›  专栏  ›  技术社区  ›  blcamp

仍然是一个“多重处置”问题,即使已处理

  •  0
  • blcamp  · 技术社区  · 7 年前

    在我的一些项目中,我使用了一对经过验证的数据加密/解密方法(下面粘贴了加密方法)。但是我一直被这个关于memoryStream对象的唠叨的CA2202警告(“不要多次处理对象”)困扰着。我相信我以适当的方式处理了这个问题,但是每当我在visualstudio中运行分析时仍然会收到警告。它从未在生产代码中抛出异常,但我仍然希望彻底消除警告。有可能吗?或者我应该忽略它?提前谢谢。

    public static string Encrypt(string clearText, string passPhrase, string saltValue)
    {
        byte[] clearTextBytes = Encoding.UTF8.GetBytes(clearText);
        byte[] saltValueBytes = Encoding.UTF8.GetBytes(saltValue);
    
        Rfc2898DeriveBytes passPhraseDerviedBytes = new Rfc2898DeriveBytes(passPhrase, saltValueBytes);
        byte[] keyBytes = passPhraseDerviedBytes.GetBytes(32);
        byte[] initVectorBytes = passPhraseDerviedBytes.GetBytes(16);
    
        RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC };
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
    
        byte[] cipherTextBytes = null;
        MemoryStream memoryStream = null;
        try
        {
            memoryStream = new MemoryStream();
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
            {
                cryptoStream.Write(clearTextBytes, 0, clearTextBytes.Length);
                cryptoStream.FlushFinalBlock();
                cipherTextBytes = memoryStream.ToArray();
            }
        }
        finally
        {
            if (memoryStream != null)
            {
                memoryStream.Dispose();
            }
        }
    
        return Convert.ToBase64String(cipherTextBytes);
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Guy    7 年前

    是因为 CryptoStream memoryStream

    您正在使用构造函数

    public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
        : this(stream, transform, mode, false) {
    }
    

    哪个电话

    public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen) {
        _stream = stream;
        _leaveOpen = leaveOpen;
        //...
    }
    

    _leaveOpen _stream 以后用于 Dispose

    protected override void Dispose(bool disposing) {
        try {
            if (!_leaveOpen) {
                _stream.Close();
            }
            //...
        }
    }
    

    您可以删除 memoryStream.Dispose(); ,或通过 true 作为参数 标准接口 建造师

    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write, true)) { }
    

    github source code reference

        2
  •  1
  •   Camilo Terevinto Chase R Lewis    7 年前

    CryptoStream.Dispose 可以 对给定流调用dispose:

    protected override void Dispose(bool disposing) 
    {
        try 
        {
            if (disposing) 
            {
                if (!_finalBlockTransformed) 
                {
                    FlushFinalBlock();
                }
                if (!_leaveOpen) 
                {
                    _stream.Close();
                }
            }
        }
        ...
    }
    

    如果使用接受4个参数的构造函数:

    CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen)
    

    最后一个参数决定流是否关闭。使命感 Close() Dispose :

    public virtual void Close()
    {
        /* These are correct, but we'd have to fix PipeStream & NetworkStream very carefully.
        Contract.Ensures(CanRead == false);
        Contract.Ensures(CanWrite == false);
        Contract.Ensures(CanSeek == false);
        */
    
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    

    MemoryStream 在大多数情况下并不重要。