In your 任务管理器,转到View菜单来选择要在其中显示的列流程标签。选择您想要显示的GDI 对象柱子。我相当肯定您会看到进程的 GDI 对象总数达到 10000,这是任何进程的最大值。
这与使用了多少物理内存无关。从这个意义上说,该错误消息非常糟糕且具有误导性。问题是您已经用完了 GDI 句柄。 Windows 下的每个进程都限制其可以创建的 GDI 句柄的最大数量。当前每个进程的限制为 10000 个句柄。
我假设您的问题是 GDI 句柄的原因是因为在绘制控件的过程中尝试创建新位图时会引发异常。位图是一个 GDI 对象。创建位图会使用该位图的 GDI 句柄。因此,这很可能是原因。
由于错误发生在标准中ToolStrip
控制,这不太可能是一个错误ToolStrip
,本身。更有可能的是,您在程序的其他地方用完了所有 GDI 句柄,然后,当控件尝试绘制自身时,它会失败,因为没有剩余的句柄。
每当您创建 GDI 对象(例如笔和位图)时,您都需要确保释放这些对象。所有获取 GDI 句柄的 GDI 类都实现IDisposable
界面。当对象被处理时,它们会自动删除此时的句柄。但是,如果您从不处理这些对象,则句柄永远不会被删除,并且您的 GDI 对象数量只会不断增长。
处置任何IDisposable
对象,您可以简单地调用Dispose
完成对象后的方法,例如:
Dim b As New Bitmap("test.bmp")
'...
b.Dispose()
但是,如果可以的话,最好声明变量IDisposable
对象具有Using
块,像这样:
Using b As New Bitmap("test.bmp")
'...
End Using
随着Using
块,Dispose
方法将自动为您调用,因此您无需自己显式调用它。原因是Using
阻止比调用更好Dispose
你自己是因为,如果在内部抛出异常Using
块,Dispose
方法仍然会被自动调用。如果您自己明确调用它,而不带Using
块,更容易错过您需要调用它的每个地方。
要查找代码中的问题区域,请在调试器中运行程序并单步执行代码。留下任务管理器打开,显示GDI 对象列,当您单步执行代码时。看着GDI 对象栏目中的任务管理器随着新 GDI 对象的创建,您将看到计数增加。使用这种方法应该很容易找出问题所在。