使用和垃圾收集

时间:2009-03-17 20:28:01

标签: c# garbage-collection using

您好,只是为了澄清我是否有以下内容:

using (Object1) {
create Object2
}
// bookmark1

将Object2与Object1一起销毁在书签1中吗? Object2是StringReader,Object1是MemoryStream。

4 个答案:

答案 0 :(得分:18)

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

Object1将是 Disposed ,一个不同的概念; Object2没有任何反应。

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

有关详情,请参阅MSDN上的IDisposable

答案 1 :(得分:2)

使用块对于像这样的构造来说真的是语法糖:

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

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

答案 2 :(得分:1)

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

如果你想要正确地“清理”这两个对象,它们都需要被处理掉,或者通过将它们包装在using语句中,或者手动调用Dispose。

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

using (Object1 obj1 = new Object1(), Object2 obj2 = new Object2())
{
    // Do something with obj1 & obj2
}

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

有关详细信息,请参阅MSDN's page on using.

答案 3 :(得分:0)

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

另外,如果object2也是IDisposable,你可以这样做:

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

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

相关问题