CA2000/CA2202 用于 using 语句中的流



CA2000和CA2202警告最近一直是我存在的祸根。我在这里做错了什么?我基本上使用File.Open获取一个FileStream,然后将其传递给可能返回新流或可能返回相同流的函数。然后,我对我的流执行更多操作,然后在我的finally块中,如果它不同,我会处理我正在使用的流。

我收到两个 CA 警告。 2000 表示using块中的fileStream,2202 表示finally块中的changedStream。什么给?

using (Stream fileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
Stream changedStream = null;
try
{
changedStream = someCondition ? fileStream : DoSomeActionThatMayReturnNewStream(fileStream);
DoSomeMoreStuffWithStream(changedStream);
}
finally
{
if (changedStream != null && changedStream != fileStream)
{
changedStream.Dispose();
}
}
}

在什么情况下(如果有的话),DoSomeActionThatMayReturnNewStream会处置传入的流? 如果在创建新流时会释放传入的流(这通常是预期的),则由using块触发的Dispose将是多余的。

如果DoSomeActionThatMayReturnNewStream从不释放传入的流,则代码的行为似乎是正确的,但 FxCop 无法分析其复杂且非正统的对象所有权模式。 我建议最好做一些类似的事情

Stream inputFile = null;
try
{
inputFile = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
DoSomeActionThatMayReturnNewStream(ref inputFile);
DoSomeMoreStuffWithStream(inputFile);
}
finally
{
if (inputFile != null)
inputFile.Dispose();
}

如果DoSomeActionThatMayReturnNewStream要打开新流,则应处理旧流。 它应该在关闭旧流之前立即为变量清空,并在打开新流时立即分配它。 这将确保如果在方法期间发生异常,则当且仅当旧流以前未被释放时,旧流才会被释放,并且如果其构造函数完成,新流将被释放,即使DoSomeActionThatMayReturnNewStream在此之后抛出异常[如果该方法在新流上调用Dispose以防引发异常, 在这种情况下,它应该使变量为空]。

以下有什么问题:

using (var fileStream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var changedStream = someCondition ? fileStream : DoSomeActionThatMayReturnNewStream(fileStream))
{
DoSomeMoreStuffWithStream(changedStream);
}
}

相关内容

  • 没有找到相关文章

最新更新