使用和垃圾收集

如果我有以下内容,你好只是为了clairfy:

using (Object1) { create Object2 } // bookmark1 

将Object2与Object1一起销毁到Object2吗? Object2是StringReader,Object1是MemoryStream。

两个对象都不会在块结束时被销毁

Object1将是Disposed ,一个不同的概念; Object2什么都不会发生。

两个对象都将被收集,并可能在稍后的时间内完成。 垃圾收集是不确定的 – 您不能依赖它何时发生。

有关详细信息,请参阅MSDN上的IDisposable 。

对于像这样的构造,using块实际上是语法糖:

 try { Brush b = new SolidBrush(Color.Red); } finally { b.Dispose(); } 

因此,’b’将被置于try块的末尾,除非发生的事情超出了应用程序的控制范围。

在块的末尾(bookmark1),在您的示例中,仅处理对象1。 对于文件流,这意味着将关闭流并释放句柄,但实际的字符串对象仍将在内存中(准备由GC清除)。 在您的情况下,Object2将不会被处理,因此它使用的句柄仍将保持打开状态。 最终,GC将收集它并调用其终结器,此时它将正确释放。

如果您希望正确“清理”这两个对象,则需要将它们都处理掉,方法是将它们包装在using语句中,或者手动调用Dispose。

还有另一种可能更清晰的语法:

 using(Object1 obj1 = new Object1(),Object2 obj2 = new Object2())
 {
     //用obj1和obj2做一些事情
 }

如果这样做,obj1 AND obj2将在块的末尾处置。 在您的情况下,这意味着将关闭两个对象,并释放它们的句柄。 然后,GC将在未来的垃圾收集中清理它们。

有关详细信息,请参阅MSDN的使用页面。

object2 不会被object1销毁(处置)。 但是,为using语句创建了一个单独的作用域块,因此此时object2确实超出了作用域。 它的处置不是确定性的。

此外,如果object2也是IDisposable,您可以这样做:

 using (object1) using (object2) { } // bookmark1 

无论如何,正常的垃圾收集规则都适用:对象的托管资源(内存)仍以正常方式处理。 使用/ IDisposable仅释放未受管理的资源。