我创建了一个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上使用它,则一切工作都可以完美完成。即使我不在位图上使用它也可以。这两个答案都很棒,我只能接受其中一个:(

最佳答案

因此,该错误消息来自GDI +的较深层,可能由于多种原因而出现。但是,我发现您的代码存在一个明显的问题,它是一个候选对象:

 label.Font = new Font("Arial", 20);
Font对象实现IDisposable,并且您在紧密的循环中创建了许多对象,而从未调用Dispose()。位图本身也是如此。我敢打赌,GDI的资源不足。

很难理解目前的代码。实际上,它基本上什么也没做,只是创建了大量的FontBitmap对象,因此我什至不建议将每个声明都包装在using语句中。除此之外,当您快速连续创建大量GDI对象而不处理它们时,最终将遇到此问题。

如果您需要这些对象在一段时间内有效,则需要确保稍后对它们调用Dispose()以尽可能及时地释放 native 资源(终结器将为您执行此操作,但最好不要等待它)。如果它们是本地对象,则将它们包装在using语句中,以便在块退出时调用Dispose():
using(var b = new Bitmap(w, h))
{
    // use 'b' for whatever
} // b.Dispose() is called for you

09-12 06:27