6

Im creating a Label and sometimes Im using .DrawToBitmap(). I dont know why, but after Im running my program for a while (and calling .DrawToBitmap() often) I get the exception:

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)

Somehow I cannot call this function that often. If I would radically try this:

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

I got after 5-6 secs (1000-2000 calls) the exception. What is the problem? How to avoid this?

Edit: Thank you guys for the idea with Dispose() - somehow everything is working perfect if I use it on label. Even if I dont use it on Bitmap its fine. Both of the answers are great, I can only accept 1 of them :(

2 Answers 2

7

So, that error message comes from deep down in GDI+ and may appear for a lot of reasons. I see one glaring problem with your code that is a candidate however:

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

Font objects implement IDisposable and you are creating a lot of them in a tight loop and never calling Dispose(). Same goes for the Bitmap itself. I would bet that GDI is running out of resources.

It's hard to make sense of your code as it stands. It essentially does absolutely nothing but create a ton of Font and Bitmap objects, so I can't even suggest to wrap each of those declarations in a using statement. That aside, when you create a ton of GDI objects in quick succession without disposing of them you will eventually run into this problem.

If you need these objects to be valid for some time then you need to make sure you call Dispose() on them later to release native resources in as timely a manner as possible (the finalizer will do this for you, but it's best not to wait for it to). If they are local objects then wrap them in a using statement so Dispose() will be called when the block exits:

using(var b = new Bitmap(w, h))
{
    // use 'b' for whatever
} // b.Dispose() is called for you
Sign up to request clarification or add additional context in comments.

2 Comments

Hi. At first I tried using(Bitmap...) => no change at all. But when I was using label.Dispose() at the end of each call everything was fine :) Thank you - tested it with 30.000 calls, I think thats fine now. Without label.Dispose() I get the exception after 1000-2000 calls. Never thought I have to dispose() the label.
@miri: Like @HansPassant: I would have thought disposing the label would cause an exception. I believe it is the Font and Bitmap that should be wrapped in using blocks. I don't know how you are able to get away with disposing the label without seeing how the label is used otherwise.
4

GDI+ exceptions are fairly poor, they often don't describe the real issue well. In this case it really means "the bitmap is too large". Which still doesn't it describe it well, you are actually running out of unmanaged memory. The bitmap is too large to fit the amount of memory still available.

Because you are not calling the Dispose() method on the bitmap. You can often skimp on that without noticing trouble. But not with Bitmap, it is a class that takes very little garbage collected memory but a lot of unmanaged memory. It doesn't trigger the garbage collector quick enough to let the finalizer release the unmanaged memory.

The code snippet doesn't make sense, but you'd write it like this to avoid the exception:

using (Bitmap image = new Bitmap(300, 500)) {
    label.DrawToBitmap(image, label.ClientRectangle);
}

3 Comments

I seriously, seriously hate GDI error messages... it requires experience just to diagnose the problem, which makes the message itself useless.
Thank you for the idea! Dispose() is great, but somehow I need to use it on the label.
Well, no, pretty sure you don't want to dispose the Label, that would make it disappear and crash your code. Dispose the bitmap.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.