Освобождение объекта Graphics

Освобождение объекта Graphics

Если вы внимательно читали несколько последних страниц, то могли заметить, что в некоторых примерах программного кода непосредственно вызывается метод Dispose() объекта Graphics, тогда как в других примерах этого не делается. Поскольку тип Graphics работает с самыми разными неуправляемыми ресурсами, имеет смысл освободить указанные ресурсы как можно быстрее с помощью Dispose() (не дожидаясь, когда это сделает сборщик мусора в процессе финализации). То же самое можно сказать о любом типе, поддерживающем интерфейс IDisposable. При работе с объектами Graphics нужно придерживаться следующих правил.

• Если объект Graphics был создан вами непосредственно, после окончания его использования его следует освободить.

• Если вы ссылаетесь на существующий объект Graphics, его освобождать не следует.

Для того чтобы это стало более понятным, рассмотрите следующий обработчик события Paint.

private void MainForm Paint(object sender, PaintEventArgs e) {

 // Загрузка локального файла *.jpg.

 image myImageFile = Image.FromFile("landscape.jpg");

 // Создание нового объекта Graphics на основе изображения.

 Graphics imgGraphics = Graphics.FromImage(myImageFile);

 // Визуализация новых данных.

 imgGraphics.FillEllipse(Brushes.DarkOrange, 50, 50, 150, 150);

 // Нанесение изображения на форму.

 Graphics g = e.Graphics;

 g.DrawImage(myImageFile, new PointF(0.0F, 0.0F));

 // Освобождение созданного нами объекта Graphics.

 imgGraphics.Dispose();

}

На данном этапе обсуждения не беспокойтесь о том, что некоторые элементы программной логики GDI+ могут быть для вас не вполне понятны. Однако обратите внимание на то, что здесь объект Graphics получается из файла *.jpg, загружаемого (с помощью статического метода Graphics.FromImage()) из локального каталога приложения. Поскольку объект Graphics создается явно, после окончания использовании этого объекта лучше использовать Dispose(), чтобы освободить внутренние ресурсы и сделать их снова доступными для использования другими компонентами системы.

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

В связи с этим заметим, что если вы забудете вызвать метод Dispose() для объекта, реализующего IDisposable, внутренние ресурсы будут освобождены позже, при обработке объекта сборщиком мусора (см. главу 5). В этом смысле освобождение объекта imgGraphics, строго говоря, не является необходимым. Так что, хотя явное освобождение объектов GDI+, созданных вами непосредственно, делает программный код совершеннее, мы с вами, чтобы сделать примеры программного кода в этой главе более краткими, не будем освобождать каждый тип GDI+ вручную.