使用CA2202包装多个IDisposables

时间:2014-05-14 13:51:11

标签: c# idisposable

当我在这样的使用中包装IDisposable对象时,我得到代码分析警告代码分析错误CA2202: Do not dispose objects multiple timeshttp://msdn.microsoft.com/en-us/library/ms182334.aspx

using (StringWriter textWriter = new StringWriter())
{
    using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
    {
        serializer.Serialize(xmlWriter, value);
    }
    return textWriter.ToString();
}

然而,这不会返回任何错误

using (StringWriter textWriter = new StringWriter())
{
    XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings);
    serializer.Serialize(xmlWriter, value);
    return textWriter.ToString();
}

此时,xmlWriter dispose将触发CA2202

StringWriter textWriter = null;
XmlWriter xmlWriter = null;

try
{
    textWriter = new StringWriter();
    xmlWriter = XmlWriter.Create(textWriter, settings);
    serializer.Serialize(xmlWriter, value);
    return textWriter.ToString();
}
finally
{
    if (textWriter != null)
        textWriter.Dispose();
    // The xmlWriter dispose will trigger CA2202
    if (xmlWriter != null)
        xmlWriter.Dispose();
}

我应该使用哪种模式?不丢弃一次性元素似乎很奇怪。

2 个答案:

答案 0 :(得分:2)

正在处理内部使用声明XmlWriter的结尾。发生这种情况时,textWriter元素也会被释放,因为XmlWriter在内部处理它包装的对象。

由于Dispose应该是幂等的(可重复调用没有副作用)我不会担心这个警告。

答案 1 :(得分:1)

一个简单的谷歌找到这个答案:https://stackoverflow.com/a/8096857/2027232

问题不在于嵌套使用。他们很好,一般建议。这里的问题是XmlReader如果您使用TextReader传递XmlReaderSettings,则会处置CloseInput == true,但CA2202规则不够智能,您的代码将无法运行那个分支。保持嵌套使用,并将CA2202违规视为误报。如果您需要格外小心,请使用设置为XmlReaderSettings的{​​{1}} CloseInput,但这是默认值,因此并非绝对必要。

BTW,对于各种流和阅读器类型,存在类似的CA2202问题场景。不幸的是,它们并不完全相同,所以最佳案例处理方式可能会有所不同,具体取决于导致问题的类型。