繁体   English   中英

DrawToBitmap - System.ArgumentException:参数无效

[英]DrawToBitmap - System.ArgumentException: Parameter is not valid

我创建一个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上使用它,一切都很完美。 即使我不在Bitmap上使用它也没关系。 这两个答案都很棒,我只能接受其中一个:(

因此,该错误消息来自GDI +的内心深处,可能出现很多原因。 我看到你的代码有一个明显的问题,但是:

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

Font对象实现了IDisposable ,你在紧密的循环中创建了很多它们,并且从不调用Dispose() Bitmap本身也是如此。 我敢打赌,GDI资源不足。

现在很难理解你的代码。 除了创建大量的FontBitmap对象之外,它基本上什么都不做,所以我甚至不建议将每个声明包装在using语句中。 除此之外,当你快速连续创建大量GDI对象而不处理它们时,你最终会遇到这个问题。

如果您需要这些对象有效一段时间,那么您需要确保稍后调用Dispose()以尽可能及时地释放本机资源(终结器将为您执行此操作,但最好不要等待它)。 如果它们是本地对象,则将它们包装在using语句中,以便在块退出时调用Dispose()

using(var b = new Bitmap(w, h))
{
    // use 'b' for whatever
} // b.Dispose() is called for you

GDI +异常相当差,它们通常不能很好地描述真正的问题。 在这种情况下,它实际上意味着“位图太大”。 它仍然不能很好地描述它,你实际上已经耗尽了非托管内存。 位图太大,无法容纳仍然可用的内存量。

因为您没有在位图上调用Dispose()方法。 你可以经常在不注意麻烦的情况下吝啬。 但是不是Bitmap,它是一个类,它只需要很少的垃圾收集内存,但需要很多非托管内存。 它不会足够快地触发垃圾收集器,让终结器释放非托管内存。

代码片段没有意义,但您可以这样写它以避免异常:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM