Когда мне нужно использовать dispose () для графики?

Я учусь рисовать на C # и все время вижу рекомендации по использованию dispose (), но не совсем понимаю, что он делает.

  • Когда мне следует использовать dispose () для рисованной графики?
  • Что будет, если я этого не сделаю?
  • Нужно ли мне вызывать его каждый раз, когда изображение не отображается, например, в графическом интерфейсе, в котором есть вкладки, и пользователь переключился на другую вкладку, а затем перерисовывать его, когда они переключаются обратно?
  • Смогу ли я что-нибудь сломать, если позвоню, когда не должен?
  • Сможет ли Бэтмен вырваться из тисков зла Джокера?

person lala    schedule 03.07.2010    source источник


Ответы (4)


  • Когда следует использовать dispose () для рисованной графики? Когда вы полностью закончите работу с любым объектом, реализующим IDisposable, вы должны вызвать Dispose непосредственно перед тем, как он станет подходящим для сборки мусора. Как указывали другие, лучше использовать оператор using вместо прямого вызова Dispose.
  • Что произойдет, если я этого не сделаю? Ваша программа будет немного менее эффективной, поскольку она потребует немного больше ресурсов, чем необходимо. Это единственный недостаток отказа от удаления графики, однако отказ от удаления других классов на самом деле может вызвать ошибки (один известный пример - StreamWriter). По этой причине лучше всегда удалять любой класс, реализующий IDisposable, как общее правило.
  • Нужно ли мне вызывать его каждый раз, когда изображение не отображается, например, в графическом интерфейсе пользователя, который имеет вкладки, и пользователь переключился на другую вкладку, а затем перерисовывать его при переключении обратно? Нет. Объекты следует утилизировать только после того, как вы полностью с ними покончили.
  • Я сломаю что-нибудь, если позвоню, когда не должен? Да. Если вы вызовете Dispose до того, как закончите работу с объектом, а затем попытаетесь использовать удаленный объект, вы получите ObjectDisposedException.
  • Сможет ли Бэтмен вырваться из тисков злых лап Джокера? Настройтесь на завтра, то же время, то же время битвы!
person Stephen Cleary    schedule 03.07.2010
comment
Для этого нужно еще одно правило: не удаляйте объект, который вы не создавали. Удаление e.Graphics - неприятная скрытая ошибка. - person Hans Passant; 03.07.2010
comment
Просто примечание для Graphics, в частности, если он был удален, вызов его методов Draw... выдаст InvalidArgumentException с сообщением «параметр недействителен», а не ObjectDisposedException. - person reve_etrange; 19.02.2015

Когда вы запрашиваете графический объект, Windows выделяет вам немного памяти. Вызов утилиты очистит память за вас. Если вы не вызовете dispose, все эти дескрипторы памяти останутся открытыми, и в конечном итоге ваша система исчерпает ресурсы, станет медленнее и в конечном итоге остановится (однако закрытие программы может освободить их).

Поскольку вы используете .NET, когда вы закончите использовать свой графический объект, сборщик мусора в конечном итоге вызовет за вас dispose. Проблема со сборщиком мусора заключается в том, что вы никогда не знаете, когда он очистит объект, поэтому он может оставить эти ресурсы открытыми дольше, чем необходимо.

При этом вам никогда не придется призывать себя распоряжаться. Намного лучше будет поместить ваш объект в область видимости:

using(Graphics g)
{
    // do something with the resource
}

Теперь, когда вы покинете эту область видимости, объект будет уничтожен, и для вас автоматически будет вызвано удаление. Вы должны поместить все объекты, для которых определен метод dispose, в область using.

person DanDan    schedule 03.07.2010

Говоря языком новичков, Dispose () предназначен для очистки после того, как вы закончили использовать неуправляемый ресурс.

Что такое неуправляемый ресурс? Это все, чем CLR не управляет за вас. Это такие вещи, как дескрипторы файлов, подключения к базам данных, сетевые сокеты, ручки GDI + и т. Д. Вы получаете доступ к этим вещам через типичный объект .NET, но он будет реализовывать IDisposable, чтобы вы могли правильно очистить.

Зачем убирать? Пока вы не уберете за собой, этот ресурс будет недоступен для использования другими частями программы. В этом отношении вы ломаете вещи, потому что тратите ресурсы.

Зачем это делать самому? Вы должны сделать это самостоятельно, как только перестанете нуждаться в ресурсе, а не полагаться на автоматическую магию сборщика мусора, потому что это может занять много времени (ну, не указано) количество времени, прежде чем сборщик мусора доберется до него. Пока объект не был удален должным образом, вы не можете повторно использовать базовый ресурс, поэтому ваша программа не будет работать надежно.

person Frederik    schedule 03.07.2010

Митч Уит говорит: «Всегда вызывайте Dispose () для любого объекта, который реализует IDisposable. Дескрипторы GDI, используемые графическими объектами, неуправляемы и требуют удаления, когда вы закончите с ними.

person kv-prajapati    schedule 03.07.2010