Утилизация статической кисти - PullRequest
3 голосов
/ 23 января 2009

Я пишу приложение для биоритмов. Чтобы проверить это, у меня есть форма с кнопкой и PictureBox. Когда я нажимаю на кнопку, я делаю

myPictureBox.Image = GetBiorhythm2();

, который работает нормально в первый раз, , но при втором щелчке это вызывает следующее исключение:

System.ArgumentException: Parameter is not valid.
   at System.Drawing.Graphics.CheckErrorStatus
   at System.Drawing.Graphics.FillEllipse
   at Larifari.Biorhythm.Biorhythm.GetBiorhythm2 in c:\delo\Horoskop\Biorhythm.cs:line 157
   at Larifari.test.Button1Click in c:\delo\Horoskop\test.Designer.cs:line 169
   at System.Windows.Forms.Control.OnClick
   at System.Windows.Forms.Button.OnClick
   at System.Windows.Forms.Button.OnMouseUp
   at System.Windows.Forms.Control.WmMouseUp
   at System.Windows.Forms.Control.WndProc
   at System.Windows.Forms.ButtonBase.WndProc
   at System.Windows.Forms.Button.WndProc
   at ControlNativeWindow.OnMessage
   at ControlNativeWindow.WndProc
   at System.Windows.Forms.NativeWindow.DebuggableCallback
   at ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
   at ThreadContext.RunMessageLoopInner
   at ThreadContext.RunMessageLoop
   at System.Windows.Forms.Application.Run
   at Larifari.test.Main in c:\delo\Horoskop\test.cs:line 20

функция сокращения, которая вызывает ошибку:

public static Image GetBiorhythm2() {
        Bitmap bmp = new Bitmap(600, 300);
        Image img = bmp;
        Graphics g = Graphics.FromImage(img);

        Brush brush = Brushes.Black;
        g.FillEllipse(brush, 3, 3, 2, 2); //Here the exception is thrown on the second call to the function

        brush.Dispose(); //If i comment this out, it works ok.

        return img;
 }

Если я закомментирую утилизацию щетки, она будет работать нормально, но я не доволен этим и хочу найти альтернативное решение. Можете ли вы помочь мне, пожалуйста?

Ответы [ 3 ]

14 голосов
/ 23 января 2009

Bruhes.Black является системным ресурсом и не предназначен для вас. Среда выполнения управляет кистями в классе Brushes, Pens и другими подобными объектами. Он создает и удаляет эти объекты по мере необходимости, сохраняя часто используемые элементы живыми, чтобы ему не приходилось постоянно создавать и уничтожать их.

Документация для класса Brushes гласит:

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

Короче говоря, не вызывайте Dispose для поставляемых системой объектов.

11 голосов
/ 23 января 2009

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

    Brush brush = Brushes.Black;
    g.FillEllipse(brush, 3, 3, 2, 2); //Here the exception is thrown on the second call to the function

    brush.Dispose(); //If i comment this out, it works ok.

Когда вы устанавливаете brush = Brushes.Black, вы фактически устанавливаете кисть как ссылку (или указатель) на статический Brushes.Black. Располагая им, вы фактически пишете:

    Brushes.Black.dispose();

Когда вы возвращаетесь, чтобы снова использовать черную кисть, среда выполнения говорит, что вы не можете, потому что она уже удалена и не является допустимым аргументом для g.FillEllipse ()

Лучший способ написать это может быть просто:

    g.FillEllipse(Brushes.Black, 3, 3, 2, 2);

Или, если вы хотите быть действительно сложным с этим:

    Brush brush = Brushes.Black.Clone();
    g.FillEllipse( brush, 3, 3, 2, 2 );
    brush.Dispose();

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

3 голосов
/ 23 января 2009

Я не думаю, что вам нужно вызывать. Удаляйте статические кисти, только если вы создаете новые. Хотя, лично я бы использовал синтаксис использования .. т.е.:

using (Brush brush = new SolidBrush(...))
{
    g.FillEllipse(brush, 3, 3, 2, 2);
}

И, вероятно, вы должны сделать то же самое с графическим объектом, который вы создаете.

...