简体   繁体   English

DrawToBitmap - System.ArgumentException:参数无效

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

Im creating a Label and sometimes Im using .DrawToBitmap() . 我创建一个Label ,有时我使用.DrawToBitmap() I dont know why, but after Im running my program for a while (and calling .DrawToBitmap() often) I get the exception: 我不知道为什么,但在我运行我的程序一段时间后(经常调用.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)

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. 我得到了5-6秒(1000-2000个电话)的异常。 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 . 编辑:谢谢你们使用Dispose()的想法 - 不知怎的,如果我在label上使用它,一切都很完美。 Even if I dont use it on Bitmap its fine. 即使我不在Bitmap上使用它也没关系。 Both of the answers are great, I can only accept 1 of them :( 这两个答案都很棒,我只能接受其中一个:(

So, that error message comes from deep down in GDI+ and may appear for a lot of reasons. 因此,该错误消息来自GDI +的内心深处,可能出现很多原因。 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() . Font对象实现了IDisposable ,你在紧密的循环中创建了很多它们,并且从不调用Dispose() Same goes for the Bitmap itself. Bitmap本身也是如此。 I would bet that GDI is running out of resources. 我敢打赌,GDI资源不足。

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. 除了创建大量的FontBitmap对象之外,它基本上什么都不做,所以我甚至不建议将每个声明包装在using语句中。 That aside, when you create a ton of GDI objects in quick succession without disposing of them you will eventually run into this problem. 除此之外,当你快速连续创建大量GDI对象而不处理它们时,你最终会遇到这个问题。

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). 如果您需要这些对象有效一段时间,那么您需要确保稍后调用Dispose()以尽可能及时地释放本机资源(终结器将为您执行此操作,但最好不要等待它)。 If they are local objects then wrap them in a using statement so Dispose() will be called when the block exits: 如果它们是本地对象,则将它们包装在using语句中,以便在块退出时调用Dispose()

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

GDI+ exceptions are fairly poor, they often don't describe the real issue well. GDI +异常相当差,它们通常不能很好地描述真正的问题。 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. 因为您没有在位图上调用Dispose()方法。 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. 但是不是Bitmap,它是一个类,它只需要很少的垃圾收集内存,但需要很多非托管内存。 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);
}

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

相关问题 System.ArgumentException:参数无效 - System.ArgumentException: Parameter is not valid System.ArgumentException:“参数无效”内存流到图像 - System.ArgumentException: "Parameter is not Valid" Memorystream to Image 参数无效-System.argumentException-图像处理 - Parameter not valid - System.argumentexception - Image Handling ImageResizer-转换PSD文件时出错-System.ArgumentException:参数无效 - ImageResizer - Error converting PSD file - System.ArgumentException: Parameter is not valid System.ArgumentException:参数无效。 GraphicsPath.AddString - System.ArgumentException: Parameter is not valid. GraphicsPath.AddString System.ArgumentException:参数无效。 在C#中 - System.ArgumentException: Parameter is not valid. in C# 计时器中graphics.DrawLine上的“ System.ArgumentException参数无效” - 'System.ArgumentException parameter is not valid' at graphics.DrawLine in a timer System.ArgumentException:'参数无效。 (showDialog错误) - System.ArgumentException: 'Parameter is not valid.' (showDialog error) System.ArgumentException:“不是有效的默认值参数名称:defaultValue”(NControl) - System.ArgumentException: 'Not a valid default value Parameter name: defaultValue' (NControl) System.ArgumentException:DataGridViewComboBoxCell 值无效 - System.ArgumentException: DataGridViewComboBoxCell value is not valid
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM