6

私はを作成しLabel、時には私はを使用して.DrawToBitmap()います。理由はわかりませんが、プログラムをしばらく実行した後(そして.DrawToBitmap()頻繁に呼び出した後)、例外が発生します。

System.ArgumentException: Parameter is not valid.
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)

どういうわけか、私はこの関数をそれほど頻繁に呼び出すことができません。私がこれを根本的に試すとしたら:

while(true)
{

  System.Windows.Forms.Label label = new Label();

  label.Font = new Font("Arial", 20);
  label.Text = "test";

  try
  {
    Bitmap image = new Bitmap(300, 500);
    label.DrawToBitmap(image, label.ClientRectangle);
  }
  catch (Exception e)
  {
    Console.WriteLine(e);
  }
}

5〜6秒(1000〜2000回の呼び出し)後に例外が発生しました。何が問題ですか?これを回避する方法は?

編集:アイデアをありがとうございましたDispose()-で使用すると、どういうわけかすべてが完璧に機能していlabelます。ビットマップで使用しなくても問題ありません。両方の答えは素晴らしいです、私はそれらの1つだけを受け入れることができます:(

4

2 に答える 2

7

そのため、そのエラーメッセージはGDI +の奥深くから発生し、さまざまな理由で表示される可能性があります。ただし、候補となるコードに1つの明白な問題があります。

 label.Font = new Font("Arial", 20);

Fontオブジェクトが実装さIDisposableれ、タイトなループでそれらの多くを作成し、を呼び出すことはありませんDispose()。ビットマップ自体についても同じことが言えます。GDIのリソースが不足しているに違いありません。

現状のコードを理解するのは難しいです。Font基本的には、大量のオブジェクトを作成するだけなので、これらの各宣言をステートメントBitmapでラップすることを提案することすらできません。usingそれはさておき、大量のGDIオブジェクトを破棄せずにすばやく連続して作成すると、最終的にこの問題が発生します。

これらのオブジェクトをしばらくの間有効にする必要がある場合は、Dispose()後でそれらを呼び出して、可能な限りタイムリーにネイティブリソースを解放する必要があります(ファイナライザーがこれを行いますが、それを待たないことが最善です)に)。それらがローカルオブジェクトである場合は、それらをusingステートメントでラップしてDispose()、ブロックが終了したときに呼び出されるようにします。

using(var b = new Bitmap(w, h))
{
    // use 'b' for whatever
} // b.Dispose() is called for you
于 2012-08-16T22:33:47.640 に答える
4

GDI +の例外はかなり貧弱で、実際の問題をうまく説明していないことがよくあります。この場合、それは実際には「ビットマップが大きすぎる」ことを意味します。それでもうまく説明されていませんが、実際には管理されていないメモリが不足しています。ビットマップが大きすぎて、まだ使用可能なメモリの量に収まりません。

ビットマップでDispose()メソッドを呼び出していないためです。多くの場合、問題に気付かずにそれを軽視することができます。ただし、ビットマップでは、ガベージコレクションされたメモリはほとんど使用されませんが、アンマネージメモリは大量に使用されます。ファイナライザーがアンマネージメモリを解放するのに十分な速さでガベージコレクターをトリガーしません。

コードスニペットは意味がありませんが、例外を回避するために次のように記述します。

using (Bitmap image = new Bitmap(300, 500)) {
    label.DrawToBitmap(image, label.ClientRectangle);
}
于 2012-08-16T22:35:21.387 に答える