同一使用块中的多个变量

本文关键字:变量 | 更新日期: 2023-09-27 17:58:24

我目前使用两个对象,如下所示:

using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
    // work with ms and bw, both referenced here
}

它"很好",事实上也是一个答案。然而,当我运行VS2012的代码分析工具时,我会收到一个警告,比如:

CA2202  Do not dispose objects multiple times   
Object 'ms' can be disposed more than once in method '<my method name>'. 
To avoid generating a System.ObjectDisposedException you should not 
call Dispose more than one time on an object.

这让我相信可能有另一种方法来处理这种情况,但我不知道它是什么

有人知道在一个using块中以无警告的方式使用两个对象的"正确"方法是什么吗?

同一使用块中的多个变量

BinaryWriter类的编写方式是,除非使用可选的构造函数参数告诉它不要这样做,否则它将在处理BinaryWriter时处理您传递给它的基础流。由于二进制写入程序正在处理基础内存流,而您也在using块中处理它,因此它将被处理两次。

现在,对于大多数类来说,这并不是一个真正的问题,因为它们应该(并且内存流)被写为在被丢弃两次时工作得很好,只要你在它被丢弃后不使用它(你没有),这样你就可以安全地忽略警告。如果您希望警告消失,您可以停止使用内存流,因为它已经被释放了。

如果您不需要对MemoryStream的对象引用,这将很好地工作

using (var bw = new BinaryWriter(new MemoryStream()))
{
    var memStream = bw.BaseStream as MemoryStream;
}

否则,请使用多次。特别是在使用.NET框架对象的情况下,因为它们是用正确的处置模式实现的。

当可能具有第二个dispose调用的对象没有正确实现dispose模式时,双using语句可能会导致问题。

PS:你这样得到同样的警告吗:

using (var memStream = new MemoryStream())
{
    using (var bw = new BinaryWriter(memStream))
    {
        // work with ms and bw
    }
}

您认为这是单个使用块是不正确的。示例中的代码是嵌套使用块的语法糖,如下所示:

using (var ms = new MemoryStream())
{
   using (var bw = new BinaryWriter(ms)) 
   {
    // work with ms and bw, both referenced here
   }
}

没有任何一种方法可以正确地纠正这种情况并避免发出警告。在内部资源包装外部资源并且它们一起超出范围的情况下,您需要查阅文档:如果约定声明内部资源的dispose方法调用了对包装对象的dispose,那么您就不需要将外部资源放在using块中。

话虽如此,在大多数文件中可能不会提及这些细节。你可以自己检查行为(通过继承和观察副作用),但你必须小心,因为最初没有记录,这种行为可能会在未来的版本中发生变化。

因此,如果你非常担心,你可以保留双重使用块(以防万一),抑制警告,并将整个块放在try{} catch (ObjectDisposedException e) {}中,以完全保护自己。

听起来有点偏执?取决于您使用的库:-)

我认为您不应该将"using(…){}"用于:

using (var ms = new MemoryStream())

因为操作系统管理内存并"处理"它!