Использование и сборка мусора - PullRequest
5 голосов
/ 17 марта 2009

Привет, только чтобы заявить о себе, если у меня есть следующее:

using (Object1) {
create Object2
}
// bookmark1

Будет ли объект 2 уничтожен в закладке 1 вместе с объектом 1? Object2 имеет StringReader, а Object1 имеет MemoryStream.

Ответы [ 4 ]

18 голосов
/ 17 марта 2009

Ни один объект не будет уничтожен в конце блока.

Object1 будет Disposed , другая концепция; с Object2 ничего не случится.

Оба объекта будут собраны и могут быть завершены через некоторое время. Сборка мусора недетерминирована - нельзя полагаться на то, когда это произойдет.

Подробнее см. IDisposable в MSDN.

2 голосов
/ 17 марта 2009

Использование блока - это действительно синтаксический сахар для такой конструкции:

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

Таким образом, 'b' будет расположен в конце блока try, если не произойдет что-то, что находится вне контроля приложения.

1 голос
/ 17 марта 2009

В конце блока (bookmark1), в вашем примере, будет удален только объект 1. В случае файлового потока это означает, что поток будет закрыт и дескриптор будет освобожден, но фактический строковый объект все еще будет в памяти (готов к очистке GC). В вашем случае Object2 не будет утилизирован, поэтому используемый им дескриптор будет по-прежнему оставаться открытым. В конце концов, GC соберет его и вызовет его финализатор, после чего он будет выпущен правильно.

Если вы хотите, чтобы оба объекта были "очищены" правильно, их нужно будет удалить либо с помощью переноса их в инструкции, либо с помощью вызова Dispose вручную.

Существует также альтернативный, потенциально более чистый синтаксис:

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

Если вы сделаете это, оба obj1 и obj2 будут расположены в конце блока. В вашем случае это означает, что оба объекта будут закрыты, а их дескрипторы отпущены. Затем сборщик мусора очистит их при следующей сборке мусора.

Подробнее см. Страница MSDN по использованию.

0 голосов
/ 17 марта 2009

объект2 будет не уничтожен (уничтожен) объектом1. Однако для оператора using создается отдельный блок контекста, поэтому object2 выходит из области действия на этом этапе. Это распоряжение не является детерминированным.

Кроме того, если object2 также является IDisposable, вы можете сделать это:

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

Независимо от того, что применяются обычные правила сборки мусора: управляемые ресурсы (память) для объекта по-прежнему обрабатываются обычным образом. Использование / IDisposable только освобождает неуправляемые ресурсы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...