0

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

我收到两个 CA 警告。2000 用于fileStream块内using,2202 用于changedStream块内finally。是什么赋予了?

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();
        }
    }
}
4

2 回答 2

1

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

如果从不处理传入的流,您的代码的行为似乎是正确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在抛出异常的情况下调用新流,则在这种情况下它应该使变量为空]。

于 2014-02-19T19:03:42.390 回答
0

以下有什么问题:

using (var fileStream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (var changedStream = someCondition ? fileStream : DoSomeActionThatMayReturnNewStream(fileStream))
    {
        DoSomeMoreStuffWithStream(changedStream);
    }
}
于 2014-02-19T19:26:42.257 回答