Да, вы должны избавиться от них - не только пером и кистью, но также Bitmap
и Graphics
.
Они не получают удаляются, когда они выходят за пределы области видимости, потому что сами переменные являются ссылками, а не объектами, и компилятор C # не знает, принадлежит ли право собственности этим ссылкам или нет (например, FillEllipse
теоретически может помнить ссылку, которую он дал, и попробуйте использовать ее позже - помните, что компилятор языка не имеет никаких специальных знаний о семантике библиотеки!).
Если вы хотите указать, что владение ограничено этой областью, вы используете оператор using
:
using (Bitmap bmp = new Bitmap ( 100, 100 ))
using (Graphics g = Graphics.FromImage ( bmp ))
using (Pen p = new Pen ( Color.FromArgb ( 128, Color.Blue ), 1 ))
using (Brush b = new SolidBrush ( Color.FromArgb ( 128, Color.Blue ) ))
{
g.FillEllipse ( b, 0, 0, 99, 99 );
g.FillRegion ( b, pictureBox1.Region );
}
При необходимости компилятор автоматически вставляет вызовы Dispose
,обеспечение удаления всех объектов после выхода из соответствующей области с использованием
(как правило, путем передачи управления, такой как return
или break
, либо исключение).
Если вы работаете с C ++, то использование
в C # прямо аналогично const std :: auto_ptr
, за исключением того, что здесь это языковая конструкция, и может использоваться только для локальные переменные (т.е. не для полей классов).
C # не «разрушает» и не удаляет вещи сразу после их выхода. области.
Эти классы будут , скорее всего, автоматически освободят неуправляемые ресурсы, которые они удерживают в своем специальном методе Finalizer
, который будет вызываться при сборке мусора на неопределенное время после выхода из области видимости.
Но полагаться на это - значит полагаться на то, что находится вне вашего контроля и может не произойти какое-то время.
Если класс реализует IDisposable, лучший способ для вас чтобы вручную вызвать Dispose ()
где-нибудь, или предпочтительно заключить его в с использованием блока
. Таким образом вы можете быть уверены, что:
A. Неуправляемые ресурсы определенно освобожден.
B. Неуправляемые ресурсы освобождены как можно скорее.
Dispose используется для удаления неуправляемых ресурсов.
Итак, как правило, я заключаю любые экземпляры объектов IDisposable в оператор using, поэтому мне не нужно беспокоиться о том, какой неуправляемый ресурс есть у Pen.
Я знаю, что другие люди помещали сюда примеры кода, но я начал, так что закончу:
using (Bitmap bmp = new Bitmap(100, 100))
{
using (Graphics g = Graphics.FromImage(bmp))
{
using (Pen p = new Pen(Color.FromArgb(128, Color.Blue), 1))
{
using (Brush b = new SolidBrush(Color.FromArgb(128, Color.Blue)))
{
g.FillEllipse(b, 0, 0, 99, 99);
g.FillRegion(b, pictureBox1.Region);
pictureBox1.BackColor = Color.Transparent;
pictureBox1.Image = bmp;
}
}
}
}
Я всегда использую , используя
в моем коде, поскольку он вызывает Dispose ()
для вашего объекта автоматически, даже если в блоке с использованием
возникло исключение. . Я часто использую его для проектов SharePoint (но это уже другая история ...).
Да, bmp, g, b и p - все IDisposable, вы должны Dispose () все из них. Предпочтительно использовать using () {}
блоки.
Существуют исключения, когда вы используете Pen p2 = Pens.Blue;
вам не следует удалять p2. Это называется товаром на складе. То же самое для кистей. Черный и т. Д.
Что касается почему , то оно одинаково для всех одноразовых классов. .Net не использует подсчет ссылок, поэтому нет (не может быть) немедленных действий, когда ссылка выходит за пределы области действия.
И оставление этого сборщику мусора в конечном итоге освободит их, но это (очень) неэффективно. Я знаю приложение ASP.NET (!), Которое не удалось из-за нехватки графических дескрипторов из-за того, что они не были своевременно удалены. Он генерировал изображения.