Подтвердить что ты не робот

Когда нужно утилизировать?

Когда у вас есть код:

Bitmap bmp = new Bitmap ( 100, 100 );
Graphics g = Graphics.FromImage ( bmp );

Pen p = new Pen ( Color.FromArgb ( 128, Color.Blue ), 1 );
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;

Вам нужно убрать ручку и кисть? Как насчет bmp и g?

Мой главный вопрос: если они должны быть удалены вручную, почему бы им не разобраться, как только они выйдут из сферы действия? Это то, что произойдет, если вы не уничтожили их вручную? Это задержка, которая заставляет людей делать это вручную?

4b9b3361

Ответ 1

Да, вы должны их уничтожить - не только ручку и кисть, но и Bitmap и Graphics.

Они не удаляются, когда они выходят из области видимости, потому что сами переменные являются ссылками, а не объектами, а компилятор С# не знает, принадлежит ли принадлежность к этим ссылкам или нет (например, 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 автоматически по мере необходимости, гарантируя, что все объекты будут расположены после того, как оставлена ​​соответствующая область using (как правило, путем передачи управления, например, return или break, или исключение).

Если вы исходите из фона С++, using в С# напрямую аналогичен const std::auto_ptr, за исключением того, что здесь строится язык и может использоваться только для локальных переменных (т.е. не для полей класса).

Ответ 2

Я знаю, что другие люди приводили примеры кода здесь, но я начал так, я закончу:

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;
      }
    }
  }
}

Я всегда использую using в своем коде, так как он автоматически вызывает Dispose() на вашем объекте, даже если в блоке using есть исключение. Я использую его много для проектов SharePoint (но это другая история...).

Ответ 3

С# не "разрушает" или не уничтожает вещи, как только они выходят из сферы действия.

Эти классы будут наиболее вероятно автоматически освобождать неуправляемые ресурсы, которые они удерживают, в своем специальном методе Finalizer, который будет вызываться, когда они будут собирать мусор в неопределенное время после выхода из сфера.

Но полагаться на то, чтобы полагаться на то, что находится вне вашего контроля, и может не произойти какое-то время.

Если класс реализует IDisposable, лучше всего вам вручную вызвать Dispose() где-нибудь или, предпочтительно, обернуть его в блок using. Таким образом, вы можете быть уверены, что:

а. Неуправляемые ресурсы определенно будучи освобожденным.

В. Неуправляемые ресурсы освобождаются как можно скорее.

Ответ 4

Если одноразовый шаблон используется правильно, Dispose не является строго необходимым - он будет вызываться, когда объект будет завершен, поэтому вы не будете утечки ресурсов или чего-либо еще.

Тем не менее, хорошие способы вызвать Dispose, как только вы закончите использовать объект, поскольку одноразовые средства часто напрямую контролируют собственные ресурсы, которые обычно ограничены. Объекты обычно не могут быть окончательно собраны/собраны сразу, поэтому эти ресурсы просто висят вокруг, теряются, как только вы больше не используете объект. Утилизация освобождает эти ресурсы немедленно, поэтому их можно использовать другими частями программы (или, в некоторых случаях, другими программами).

Примечание. Блок using автоматически удаляет объект, когда вы закончите с ним, поэтому вы редко видите когда-либо Dispose в блоке using.

Краткая версия: если объект реализует IDisposable, и ваш код создал его (то есть: если это не системный объект, например Pens.Blue, или Graphics, который вы передали в OnPaint и т.д.), он должен быть удаленным, когда вы полностью с ним справитесь - либо путем вызова Dispose, либо путем вызова другого метода, который указан для вызова Dispose (Close является общим), либо с помощью блока using, Вам не нужно распоряжаться им, но вы почти всегда должны.

Ответ 5

Да, bmp, g, b и p все IDisposable, вы должны Dispose() все из них. Предпочтительно, используя блоки using() {}.

Существуют исключения, когда вы используете Pen p2 = Pens.Blue;, вы не должны распоряжаться p2. Он назвал элемент запаса. То же самое для Brushes.Black и т.д.

Что касается причин, то это одинаково для всех одноразовых классов..Net не использует подсчет ссылок, поэтому нет (не может быть) немедленного действия, когда ссылка выходит за пределы области видимости.

И оставляя его сборщику мусора, он в конечном итоге освободит их, но он (очень) неэффективен. Я знаю приложение ASP.NET(!), Которое не справилось с нехваткой графических дескрипторов из-за того, что они не сразу их удалили. Он генерировал изображения.

Ответ 6

Dispose используется для утилизации неуправляемых ресурсов.

Итак, как правило, я завершаю любые экземпляры IDisposable объектов в инструкции using, поэтому мне не нужно беспокоиться о том, что неуправляемый ресурс имеет Pen.