Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多次处理对象错误。CA2202。有更好的办法吗?_C#_Dispose - Fatal编程技术网

C# 多次处理对象错误。CA2202。有更好的办法吗?

C# 多次处理对象错误。CA2202。有更好的办法吗?,c#,dispose,C#,Dispose,如何确保以下代码以更好的方式处理所有对象?目前,代码分析告诉我 错误45 CA2202:Microsoft。用法:对象“ns”可以在方法“CPCommunicator.GetResults(string)”中多次释放。为了避免生成System.ObjectDisposedException,您不应该对一个对象多次调用Dispose。:第64行,第65行 NetworkStream ns = null; StreamWriter requestStream = null; TextReader r

如何确保以下代码以更好的方式处理所有对象?目前,代码分析告诉我

错误45 CA2202:Microsoft。用法:对象“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,所以它们都会处理ns,因此为了满足代码分析警告,我必须在finally块中注释掉最后两个close方法。但是我真的想这么做吗?

是的,我觉得你真的应该只打一次电话

或者,您可以在ns上使用using语法,这使整个情况更加清楚

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

我将重构您的代码,使其如下所示:

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

尽管该建议绝对是一个好的实践,但
Dispose
的文档说明“如果对象的
Dispose
方法被多次调用,则对象必须忽略第一次调用之后的所有调用。如果对象的
Dispose
方法被多次调用,则该对象不得引发异常”@LukeH:这项建议可以被视为“良好实践”,原因只有一个:理想情况下,一个物体在其使用寿命结束时被处置,而第二次处置可能意味着甚至会导致对其真实寿命与预期寿命的混淆。但是正如您所说的,
IDisposable
的正确实现要求
Dispose
是幂等的。对,但我认为问题来自尝试关闭requestStream和responseStream。我已经用using语句包装了这三个语句,但仍然得到了代码分析错误。在requestStream关闭并处理后,在responseStream上调用close也会尝试关闭ns,这正是CA对我大吼大叫的。你不应该将这三个Using都包含在Using中,而只包含在我的响应中的ns。你是否建议我不关闭requestStream或responseStream,而只关闭networkStream?在using语句中仅包装ns并手动关闭其他两个仍然会导致错误。是的,您不应该关闭其他两个。关闭它们只会关闭底层流。在您的情况下,您已经知道这个流保证是关闭的。@Foxfire:GC从未调用
Dispose
。GC最终将调用对象的终结器,因此,
IDisposable
对象有可能提供一个“后备”终结器,在开发人员忘记处理时进行清理,但该终结器不属于
IDisposable
合同的一部分(即使这是一个好的实践)。虽然确实更干净,对于一个对象,我仍然会收到关于不在ns上多次调用dispose的相同消息。错误45 CA2202:Microsoft。用法:对象“ns”可以在方法“Communicator.GetResults(string)”中多次释放。为了避免生成System.ObjectDisposedException,您不应该对一个对象多次调用Dispose。此答案与原始问题的问题相同。