2010-05-10 63 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

相关问题