我目前正在使用以下两个对象:
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// work with ms and bw, both referenced here
}
它的工作“很好”,实际上也是an answer 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
块中以无警告的方式使用两个对象的“正确”方法是什么?
答案 0 :(得分:1)
如果您不需要MemoryStream
的对象引用,这将正常工作
using (var bw = new BinaryWriter(new MemoryStream()))
{
var memStream = bw.BaseStream as MemoryStream;
}
否则去多次使用。特别是在使用.NET框架对象的情况下,因为它们是使用正确的配置模式实现的。
当可能进行第二次置换调用的对象未正确实现置位模式时,双using
语句可能会导致问题。
PS:你这样得到同样的警告:
using (var memStream = new MemoryStream())
{
using (var bw = new BinaryWriter(memStream))
{
// work with ms and bw
}
}
答案 1 :(得分:1)
您认为这是单使用块不正确。 您的示例中的代码是嵌套使用块的语法糖,如下所示:
using (var ms = new MemoryStream())
{
using (var bw = new BinaryWriter(ms))
{
// work with ms and bw, both referenced here
}
}
没有一种方法可以正确地将其缩小并避免警告。如果内部资源包装外部资源并且它们都在一起超出范围,则需要查阅文档:如果合同声明内部资源的dispose方法调用了包装对象的处置,则根本不需要将外部资源放在using块中。
话虽如此,大多数文档中可能都没有提及此类细节。您可以自己检查行为(通过继承和观察副作用),但是您必须小心,因为首先没有记录,这种行为可能会在将来的版本中发生变化。
所以如果你非常担心它,你可以保留双重使用块(以防万一),禁止警告并将整个块放在try{} catch (ObjectDisposedException e) {}
中以完全保护自己的安全葫芦。
听起来偏执狂?取决于您正在使用的库: - )
答案 2 :(得分:1)
编写BinaryWriter类时,它会在处理BinaryWriter时处理传递给它的底层流,除非您使用可选的构造函数参数告诉它不要。由于二进制写入器正在处理底层内存流,并且您还在using
块中处理它,因此它将被丢弃两次。
现在,对于大多数类来说,这不是一个真正的问题,因为它们应该(并且内存流)写入工作得很好,如果处理两次,只要你在处理之后不使用它(你'所以你可以安全地忽略警告。如果您希望警告消失,您可以将内存流从使用中取出,因为它已经被丢弃了。
答案 3 :(得分:-4)
我认为你不应该使用“using(...){}”:
using (var ms = new MemoryStream())
因为操作系统管理内存并“处理”它!