5

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

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以无警告的方式在单个块中使用两个对象的“正确”方法是什么?

4

4 回答 4

2

BinaryWriter 类的编写方式是,它会在您释放 BinaryWriter 时释放您传递给它的基础流,除非您使用可选的构造函数参数告诉它不要这样做。由于二进制写入器正在处理底层内存流,并且您也在using块中处理它,因此它被处理了两次。

现在,对于大多数类来说,这并不是一个真正的问题,因为它们应该(并且内存流被写入)如果被释放两次就可以正常工作,只要你在它被释放后不使用它(你不是)因此您可以放心地忽略该警告。如果您希望警告消失,您可以将内存流从使用中取出,因为它已经被处理掉了。

于 2013-02-09T20:23:52.427 回答
1

如果您不需要对MemoryStreamthis 的对象引用,则可以正常工作

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

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

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

PS:您是否会以这种方式收到相同的警告:

using (var memStream = new MemoryStream())
{
    using (var bw = new BinaryWriter(memStream))
    {
        // work with ms and bw
    }
}
于 2013-02-09T19:47:54.823 回答
1

您假设这是一个单独的using 块是不正确的。您示例中的代码是嵌套 using 块的语法糖,如下所示:

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

没有单一的方法可以正确地解决这个问题并避免警告。如果内部资源包装了外部资源并且它们都超出了范围,则需要查阅文档:如果合同规定内部资源的 dispose 方法调用了包装对象的 dispose,则根本不需要将外部资源放在 using 块中。

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

所以如果你很担心的话,你可以留下双重 using 块(以防万一),抑制警告并将整个块try{} catch (ObjectDisposedException e) {}完全放在一个安全葫芦中。

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

于 2013-02-09T20:21:54.437 回答
-4

我认为您不应该将“使用(...){}”用于:

using (var ms = new MemoryStream())

因为操作系统管理内存并“处置”它!

于 2013-02-09T20:06:26.840 回答