70

我们在 Winform 应用程序中看到此错误。任何人都可以帮助您了解为什么会看到此错误,更重要的是如何修复它或避免它发生。

System.ComponentModel.Win32Exception:创建窗口句柄时出错。
   在 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   在 System.Windows.Forms.Control.CreateHandle()
   在 System.Windows.Forms.Control.CreateControl(布尔 fIgnoreVisible)
   在 System.Windows.Forms.Control.CreateControl()
   在 System.Windows.Forms.Control.OnVisibleChanged(EventArgs e)
   在 System.Windows.Forms.ButtonBase.OnVisibleChanged(EventArgs e)
4

10 回答 10

52

您是否运行过 Process Explorer 或 Windows 任务管理器来查看 GDI 对象、句柄、线程和 USER 对象?如果没有,请选择要查看的那些列(任务管理器选择查看-> 选择列...然后运行您的应用程序并查看该应用程序的这些列,看看其中一个是否变得非常大。

可能是您有一些您认为已清理但尚未处置的 UI 组件。

这是一个关于此的链接,可能会有所帮助。

祝你好运!

于 2008-10-21T18:06:09.563 回答
27

应用程序的 Windows 句柄限制为 10,000 个句柄。您收到错误是因为您的程序创建了太多句柄。您需要找到内存泄漏。正如其他用户所建议的,使用 Memory Profiler。我也使用 .Net Memory Profiler。此外,如果您在窗体关闭之前从窗体中删除它们,请确保调用控件的 dispose 方法(否则控件不会释放)。您还必须确保没有向控件注册的事件。我自己也有同样的问题,尽管我已经知道了,但我仍然有一些内存泄漏继续困扰着我。

于 2008-11-21T21:38:49.183 回答
11

请参阅我的这篇关于“创建窗口句柄时出错”的帖子以及它与用户对象和桌面堆的关系。我提供一些解决方案。

于 2009-08-08T00:35:37.800 回答
6

这个问题几乎总是与 GDI 对象计数、用户对象计数或句柄计数有关,并且通常不是因为您的机器上的内存不足。

当我跟踪其中一个错误时,我打开 ProcessExplorer 并查看以下列:句柄、线程、GDI 对象、用户对象、私有字节、虚拟大小和工作集。

(根据我的经验,问题通常是由于事件处理程序持有对象并阻止它被释放而导致的对象泄漏。)

于 2010-02-08T14:36:27.650 回答
2

好吧,就我而言,绝对是失控的用户对象。我查看了 Windows 任务管理器,果然,用户对象数正好是 10'000。

我通过将属性或列表表的容器面板的 Parent 属性设置为选项卡页的属性,在选项卡页中动态嵌入属性和列表表。我有条件地回收或重新创建属性和列表表单,具体取决于列出的集合类型或被检查对象的类类型。

注意:在 Delphi 中,所有控件都有 Owner 和 Parent 属性。即使更改了控件的 Parent 属性,当拥有的控件被销毁时,它仍然会由其所有者处置。

在 C# 中,如果通过更改 Panel.Parent 属性以编程方式将控件(例如 Panel)从 Form 重新分配到 Tab Page,则在 Form 上调用 Dispose() 不会释放 Panel,调用 Controls 也不会.Clear() 在标签页上。即使是直接调用 Panel.Dispose() 也不会真正处置它,除非它的 Parent 事先手动设置为 null 。

于 2010-03-18T12:38:47.463 回答
1

我认为这通常与计算机内存不足有关,因此它无法再创建任何窗口句柄。通常,此时 Windows 也会开始显示一些奇怪的行为。

于 2008-10-21T17:13:34.413 回答
1

我在我的应用程序中遇到了同样的错误。我在单页中加载了许多控件。在按钮单击事件中,我正在清除控件。清除控件不会从内存中释放控件。所以从内存中处理控件。我只是注释了 controls.clear() 方法并包含几行代码来处理控件。像这样的东西

对于每个 ctl 作为 controlcollection 中的控件

ctl.dispose()

下一个

于 2009-09-01T19:10:53.493 回答
1

我添加了一个检查,使它工作......

if (_form.Handle.ToInt32() > 0)
{
   _form.Invoke(method, args);
}

它总是正确的,但没有它,表单会引发错误。顺便说一句,我的句柄在 490 万左右

于 2012-03-21T19:32:03.880 回答
0

肯定有太多句柄(内存泄漏问题):

IT Jungles:System.ComponentModel.Win32Exception:创建窗口句柄时出错

于 2010-06-01T02:25:55.953 回答
-2

内存不足的建议似乎不是一个坏的线索。

你的程序在做什么,它得到这个错误?

它是否创建了大量的窗口或控件?它是否以编程方式而不是在设计时创建它们?如果是这样,您是否循环执行此操作?那个循环是无限的吗?您是否以其他方式消耗了大量的内存?

当您在任务管理器中查看应用程序使用的内存时会发生什么?它会飙升到月球吗?或者更好的是,如上所述,使用进程监视器来深入了解细节。

于 2008-10-21T18:11:55.747 回答