2010-05-10 62 views
4

如何確保以下代碼以更好的方式處理所有對象?目前,代碼分析告訴我處理對象多次錯誤。 CA2202。有沒有更好的辦法?

錯誤45 CA2202:Microsoft.Usage:對象'ns'可以在方法'CPCommunicator.GetResults(string)'中多次處理。爲了避免產生System.ObjectDisposedException你不應該調用Dispose不止一次對象:線路上:64,65

NetworkStream ns = null; 
StreamWriter requestStream = null; 
TextReader responseStream = null; 

var results = new StringBuilder(); 

try 
{ 
    ns = new NetworkStream(CreateConnection(), true); 
    requestStream = new StreamWriter(ns); 
    requestStream.Flush(); 
    responseStream = new StreamReader(ns); 

    requestStream.Write(reportData); 
    requestStream.Flush(); 
    while (responseStream.Peek() != -1) 
    { 
     var currentLine = responseStream.ReadLine(); 
     results.Append(currentLine); 
     results.Append("\n"); 
    } 
} 
finally 
{ 
    if (requestStream != null) requestStream.Close(); 
    if (responseStream != null) responseStream.Close(); 
    if (cpNetworkStream != null) cpNetworkStream.Close(); 
} 

由於兩個requestStream和responseStream使用NS,他們納秒的處置都這樣以滿足代碼分析警告,我必須在finally塊中註釋掉最後兩個close方法。但我真的想這樣做嗎?

+3

雖然推薦,絕對是很好的做法,對於'文檔Dispose'指出:「如果一個對象的'Dispose'方法被調用更多對象必須在第一次之後忽略所有的調用,如果它的'Dispose'方法被多次調用,則該對象不能拋出異常。 http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx – LukeH 2010-05-10 14:33:07

+0

@LukeH:由於一個原因,該建議可被認爲是「良好實踐」:理想情況下,一個對象放置在最後的使用壽命,再次處理它可能意味着甚至導致對其預期壽命和預期壽命的一些混淆。但正如你所說的,正確實現'IDisposable'需要'Dispose'是冪等的。 – cHao 2012-10-30 21:52:06

回答

4

是的,恕我直言,你真的應該只打一次電話。

或者,你可以在ns上使用using語法,這使得整個情況更加清晰。

using (ns = new NetworkStream(CreateConnection(), true)) { 
    ... 
} 
+0

沒錯,但我認爲問題來自嘗試關閉requestStream和responseStream。我已經將所有三種語句都包含在使用語句中,但仍然出現代碼分析錯誤。在requestStream關閉並配置之後,在responseStream上調用close會試圖關閉ns,這就是CA向我大喊的事情。 – 2010-05-10 14:34:29

+0

你不應該把所有的三個都包含在使用中,而只是包含在我的回覆中的ns。 – Foxfire 2010-05-10 15:06:54

+0

你是否暗示我不關閉requestStream或responseStream,只有networkStream?在使用語句中只包含ns並手動關閉另外兩個仍然給我錯誤。 – 2010-05-10 15:29:09

2

我會重構代碼是這樣的:

using (NetworkStream ns = new NetworkStream(CreateConnection(), true)) 
using (StreamWriter requestStream = new StreamWriter(ns)) 
using (TextReader responseStream = new StreamReader(ns)) 
{ 

    var results = new StringBuilder(); 

    requestStream.Flush(); 

    requestStream.Write(reportData); 
    requestStream.Flush(); 
    while (responseStream.Peek() != -1) 
    { 
     var currentLine = responseStream.ReadLine(); 
     results.Append(currentLine); 
     results.Append("\n"); 
    } 
} 
+0

雖然清晰,但我仍然收到關於不在對象上多次調用dispose的消息。 錯誤 CA2202:Microsoft.Usage:Object'ns'可以在方法'Communicator.GetResults(string)'中多次配置。爲避免生成System.ObjectDisposedException,您不應該在對象上多次調用Dispose。 – 2010-05-10 15:03:56

+3

此答案與原始問題具有相同的問題。 – Foxfire 2010-05-10 15:07:57

相關問題