Когда мне нужно использовать dispose () для графики? - PullRequest
20 голосов
/ 03 июля 2010

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

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

Ответы [ 4 ]

30 голосов
/ 03 июля 2010
  • Когда мне следует использовать dispose () для отрисованного кода? Всякий раз, когда вы полностью покончили с любым объектом, который реализует IDisposable, вы должны вызывать Dispose непосредственно перед ним.получает право на сборку мусора.Как отмечали другие, лучше использовать оператор using вместо прямого вызова Dispose.
  • Что произойдет, если я этого не сделаю? Ваша программа будет несколько менее эффективнойпотому что это займет немного больше ресурсов, чем необходимо.Это единственный недостаток, заключающийся в отсутствии графики ; однако , не исключая другие классы, может фактически вызвать ошибки (один известный пример - StreamWriter).По этой причине лучше всегда располагать любым классом, который реализует IDisposable, как общее правило.
  • Нужно ли вызывать его каждый раз, когда графика не видна, например, в графическом интерфейсеу которого есть вкладки, и пользователь переключился на другую вкладку, а затем перерисовал ее, когда они переключатся обратно? Нет. Объекты следует утилизировать только после того, как с ними полностью покончено.
  • Будет ли ясломать вещи, если я позвоню, когда не должен? Да.Если вы позвоните Dispose до того, как закончите работу с объектом, а затем попытаетесь использовать уничтоженный объект, вы получите ObjectDisposedException.
  • Сможет ли Бэтмен сбежать от злых когтей Джокера? Настройтесь на завтра, то же самое время бит, тот же самый канал летучей мыши!
5 голосов
/ 03 июля 2010

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

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

Это говорит о том, что вам никогда не придется звонить распоряжаться собой. Гораздо лучше будет поместить ваш объект в область действия:

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

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

3 голосов
/ 03 июля 2010

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

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

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

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

0 голосов
/ 03 июля 2010

Mitch Wheat говорит - Всегда вызывайте Dispose () для любого объекта, который реализует IDisposable.GDI-дескрипторы, используемые графическими объектами, неуправляемые и требуют утилизации, когда вы закончите с ними.

...