2014-03-07 33 views
2

我有一類這樣的...CA2202:不要釋放對象多次

public class Class1 
{ 
    public Class1() 
    { 
     byte[] plainText = new byte[1024]; 
     using (MemoryStream msEncrypt = new MemoryStream()) 
     { 
      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
      { 
       csEncrypt.Write(plainText, 0, plainText.Length); 
       csEncrypt.FlushFinalBlock(); 
       csEncrypt.Flush(); 
       encrypted = msEncrypt.ToArray(); 
      } 
     } 
    } 
    public ICryptoTransform encryptor { get; set; } 
    public byte[] encrypted { get; set; } 
} 

代碼分析拋出以下警告。不要多次處理對象。

http://msdn.microsoft.com/en-us/library/ms182334.aspx

我無法理解上面這篇文章中的這一行[示例部分] ...「嵌套使用語句(在Visual Basic中使用)可能會導致CA2202警告的違反如果嵌套內部使用的IDisposable資源語句包含外部使用語句的資源,嵌套資源的Dispose方法釋放包含的資源。當出現這種情況時,外部使用語句的Dispose方法會嘗試再次處理其資源。

IL for this code

+2

CryptoStream可能已經在配置MemoryStream。 – leppie

+2

leppie是對的,但在處置兩次沒有任何傷害,因爲它不會拋出異常。你的語法是正確的,在我看來,CryptoStream不應該觸及注入流的Dispose方法。我會主張禁止這個警告。 – Silvermind

+0

@Silvermind我同意你的看法,這是違反直覺的。我爲什麼期望'CryptoStream'能夠推出其基本流?我可能需要它以備後用。我相信這是一個糟糕的設計,這是msft選擇'IDisposable'。 –

回答

3

它指出,當你在一個資源調用Dispose,它會處理所有它擁有的資源。因此內部資源csEncrypt持有外部資源msEncryptcsEncrypt.Dispose它也將處置msEncrypt

後面的msEncrypt.Disopse被調用,因此代碼分析警告您多次調用Dispose

+1

你的處置方式錯了。 'csEncrypt'首先被處置並且處理'msEncrypt'引用的對象。 –

+0

@Damien_The_Unbeliever是的,更新了我的回答:) –

+1

+1從技術上講,'CryptoStream'似乎只是在包裝流上調用'Close',而不是處理它。考慮到文檔中的措詞,我發現有點令人驚訝(即使它們在這種情況下可能做同樣的事情) –