3

バイオリズムアプリを書いています。それをテストするために、私はボタンとPictureBoxを備えたフォームを持っています。ボタンをクリックすると、

myPictureBox.Image = GetBiorhythm2();

これは初めて正常に実行されますが、2回目のクリックで次の例外が発生します。

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

コメントアウトした場合、ブラシの廃棄は問題なく機能しますが、それに満足していないため、別の解決策を見つけたいと考えています。手伝ってくれませんか?

4

3 に答える 3

14

Bruhes.Black はシステム リソースであり、ユーザーが破棄することは意図されていません。ランタイムは、Brushes クラス、ペン、およびその他のオブジェクトのブラシを管理します。これらのオブジェクトを必要に応じて作成および破棄し、頻繁に使用されるアイテムを維持して、それらを継続的に作成および破棄する必要がないようにします。

Brushes クラスのドキュメントには次のように書かれています。

Brushes クラスには、プロパティ名で示される色の Brush オブジェクトを返す静的な読み取り専用プロパティが含まれています。新しいブラシを作成するために使用されない限り、通常、このクラスのプロパティによって返されるブラシを明示的に破棄する必要はありません。

つまり、システム提供のオブジェクトに対して Dispose を呼び出さないでください。

于 2009-01-23T02:45:17.303 に答える
11

静的を破棄しようとしているように見えますが、次に使用するときにいくつかの問題が発生します。

    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();

または、見栄えが悪くても構わない場合は、brush.Dispose(); をコメントアウトしてください。元のコードの行。

于 2009-01-23T02:46:04.273 に答える
3

新しいブラシを作成する場合にのみ、静的ブラシを呼び出す必要はないと思います。個人的には、using構文を使用します。

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

また、作成したグラフィックスオブジェクトでも同じことを行う必要があります。

于 2009-01-23T02:25:46.280 に答える