Winforms问题-创建窗口句柄时出错[重复]

Posted

技术标签:

【中文标题】Winforms问题-创建窗口句柄时出错[重复]【英文标题】:Winforms issue - Error creating window handle [duplicate] 【发布时间】:2010-09-18 08:51:58 【问题描述】:

我们在 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)

【问题讨论】:

【参考方案1】:

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

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

Here's a link 这个可能会有帮助。

祝你好运!

【讨论】:

我遇到了这个问题,发现我的应用报告了 9600+ USER Objects 和 1800+ GDI Objects。我的问题是我没有做错任何事情,我只是在 FlowLayoutPanel 中添加了很多项目。我想我将不得不“分页”显示的数据......【参考方案2】:

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

【讨论】:

【参考方案3】:

请参阅this post of mine about "Error creating window handle" 以及它与 USER 对象和桌面堆的关系。我提供了一些解决方案。

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

是的.. 我们如何解决它 您可以在测试程序时通过观察句柄、线程、GDI 对象、用户对象等的计数来解决它。如果您在执行特定活动时看到任何这些计数上升而不下降,请查看实现该活动的代码。你应该寻找一些问题,比如在你需要一个物体很久之后就抓住它。或者在循环中重复创建一个对象而不释放它。或者当您可以创建一次并引用它时不必要地重新创建一个对象。或者挂钩一个事件处理程序,然后在不先解除偶数处理程序的情况下处理对象。 这为我解决了“或者当你可以创建一次并引用它时不必要地重新创建一个对象。”【参考方案5】:

嗯,在我的情况下,肯定是 USER 对象失控了。我查看了 Windows 任务管理器,果然,USER Objects 的数量正好是 10'000。

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

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

在 C# 中,如果一个控件,例如通过更改 Panel.Parent 属性以编程方式将面板从表单重新分配到选项卡页,在表单上调用 Dispose() 不会释放面板,在选项卡页上调用 Controls.Clear() 也不会。即使是直接调用 Panel.Dispose() 也不会真正释放它,除非事先手动将其 Parent 设置为 null。

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

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

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

ctl.dispose()

下一个

【讨论】:

【参考方案8】:

我添加了一个检查以使其正常工作...

if (_form.Handle.ToInt32() > 0)

   _form.Invoke(method, args);

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

【讨论】:

请注意,Handle 属性的实现会检查是否创建了句柄,如果没有,则创建它。查看 .NET 源代码:public IntPtr Handle get ...if (!this.IsHandleCreated) this.CreateHandle(); ... IsHandleCreated 属性将在不创建句柄的情况下返回 true/false。【参考方案9】:

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

IT Jungles: System.ComponentModel.Win32Exception: Error creating window handle

【讨论】:

【参考方案10】:

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

你的程序在做什么导致这个错误?

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

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

【讨论】:

以上是关于Winforms问题-创建窗口句柄时出错[重复]的主要内容,如果未能解决你的问题,请参考以下文章

WinFrom 创建窗口句柄时出错

在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。

c#,求助!在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。

vb2013 已获得主窗口句柄,怎么遍历所有子窗句柄到TreeView中?

(转)!注意:PreTranslateMessage弹出框出错

主窗口中如何获取子窗口某控件句柄?