簡體   English   中英

即使處理,仍然是一個“多重處置”問題

[英]Still A “Multiple Dispose” Issue, Even Though Handled

在我的一些項目中,我一直在使用一對可靠的數據加密/解密方法(加密方法粘貼在下面)。 但是我一直對CA2202這個關於memoryStream對象的警告(“不要多次放置對象”)感到困惑。 我相信我會以適當的方式處理此問題,但是只要在Visual Studio中運行分析,我仍然會收到警告。 它從未在生產代碼中引發異常,但我仍然想一勞永逸地擺脫警告。 那可能嗎? 還是我應該忽略它? 提前致謝。

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);
}

這是因為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作為參數傳遞給CryptoStream構造函數

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

github源代碼參考

問題在於對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); } 

因此,該檢查似乎無法正確確定特定的Stream實現是否將被Dispose,而退回去認為它將是-這種情況。

但是請注意,在大多數情況下,對MemoryStream兩次,一次或零次處理並不重要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM