Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Выполнится ли Dispose?


Автор: Idsa 24.4.2008, 14:56
Рассмотрим два куска кода:
Код

public void A()
{
  SomeType instance = new SomeType();

  ... 
  return;

  instance.Dispose();
}

и
Код

public void A()
{
  using(SomeType instance = new SomeType());
  {
    ...
    return;
  }
}

В первом случае Dispose() не выполнится. А вот выполнится ли он во втором куске кода?

Автор: altarvic 24.4.2008, 15:09
да (даже в случае эксцепшена внутри блока)

Автор: vponomarov 24.4.2008, 15:39
Idsa, в первом случае Dispose() не выполнится т.к. он стоит после return smile 
хотя может просто опечатка...

Автор: Wanderer2019 24.4.2008, 15:43
А в случае А при выходе из метода разве Dispose не должен сам выполняться??? или в данном случае зависит от описания класса SomeType?

Автор: mullih 24.4.2008, 16:00
Цитата(Idsa @ 24.4.2008,  14:56)
Код

public void A()
{
  using(SomeType instance = new SomeType());
  {
    ...
    return;
  }
}

А вот выполнится ли он во втором куске кода?

Да если ты SomeType расширишь от интерфеса IDisposable
иначе нет или поидее не должно
Код

    class SomeType : IDisposable
    {
        public void Dispose(){}
    }


кстати и в первом случае тоже самое и Dispose не надо выывать в ручную. Он  вызывется во время сбора мусора сам. Один нюанс ты не знаеь заранее когда это произойдет за исключением если сам не заставишь дотНет собрать его

Автор: Wanderer2019 24.4.2008, 16:07
А разве GC не должен сгребать весь мусор, на который больще ничего не ссылается? 
В данном случае MyType - это локальная переменная и при выходе из метода необходимость в ней отпадает. 

Автор: mullih 24.4.2008, 16:24
GC то сгребает, Dispose как правило используют для закрытия портов, файлов, баз и тд

Автор: archeg 24.4.2008, 16:53
Цитата(Wanderer2019 @  24.4.2008,  16:07 Найти цитируемый пост)
А разве GC не должен сгребать весь мусор, на который больще ничего не ссылается? 
В данном случае MyType - это локальная переменная и при выходе из метода необходимость в ней отпадает. 

Dispose никогда не сгребает мусор который сгребает GC. GC никогда сам по себе не сгребает мусор, который сгребает Dispose (для этого исп. финализаторы). Это разный мусор smile Каждый сгребает только свой.

Добавлено через 1 минуту и 21 секунду
в блоке using, Dispose выполняется всегда, при любом выходе из блока. Будь то return, exception, или обрыв потока (генерируется ThreadAbortException)

Автор: mr.DUDA 25.4.2008, 09:30
Wanderer2019
archeg
не путаем финализацию при сборе мусора и Dispose. Слово "мусор" не применимо в одном предложении с "Dispose". GC выполнит финализацию любого объекта (кроме тех для кого вызван SuppressFinalize), т.е. вызовет деструктор при сборке мусора и высвободит память. Метод Dispose обязан вызвать программист, либо явно, либо посредством using; в реализации Dispose сборки мусора не происходит, а явно (ручками) выполняется некий код по высвобождению прочих ресурсов. Например вызов Dispose другого объекта. Или обращение к API-методу, закрывающему файл, сокет, удаляющему ресурс ОС и т.д. При сборке мусора метод Dispose не вызывается автоматически. Можно переопределить деструктор, в котором вызвать Dispose, но об этом у Рихтера лучше почитать - там замечательно расписан паттерн "финалайзер+Dispose". smile

З.Ы. мои извинения за произнесённые избитые фразы smile 

Автор: altarvic 25.4.2008, 09:51
Здесь некоторые путают финализоторы и интерфейс IDisposable (который к финализаторам вообще никакого отношения не имеет. Класс может иметь Dispose, а финализатора нет и наоборот) 
Dispose - это вспомогательный метод который служит для детерминированного (т.е. по воле программы) освобождения ресурсов, без ожидания когда это сделает GC. Соответственно чтобы не дублировать код очистки пишут примерно так:

Код

class Foo: IDisposable
{

private void FreeResources()
{
   // очистка
}

~Foo()
{
   FreeResources();
}

public void Dispose()
{
    FreeResources();
    GC.SuppressFinalize(this); // Запрещаем вызов финализатора
}


}


Автор: mr.DUDA 25.4.2008, 09:54
altarvic, ну я примерно то же самое написал.

Автор: DrunkProgrammer 25.4.2008, 11:41
Пардон, что лезу в чужую тему, но у меня проблема с высвобождением ресурсов. Есть компонента, одна из ее функций возвращает объект. Из-за этого объекта зависает процесс в памяти. Если я вместо функции делаю void и вместо строчки return ИмяОбъекта добавляю

 Marshal.Release(Marshal.GetIDispatchForObject(ИмяОбъекта));
 Marshal.ReleaseComObject(ИмяОбъекта);

 GC.Collect();
 GC.WaitForPendingFinalizers();

то процесс в памяти не зависает.
Подскажите, как можно убить этот объект.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)