C# 检测c应用程序中的windowhandle泄漏

C# 检测c应用程序中的windowhandle泄漏,c#,detect,memory-leaks,C#,Detect,Memory Leaks,我昨天遇到了一个例外: Win32Exception: Fehler beim Erstellen des Fensterhandles 可以翻译为: Win32Exception: Error while creating the windowhandle 我知道如何解决这个问题,甚至为此写了一篇短文——用德语 但我不知道我的应用程序可能会在哪里“泄漏”未处理的控件,这些控件仍然有窗口句柄 是否有任何方法可以检测/查找 实现IDisposable 具有父项==null 与此约束匹配的对象似乎是

我昨天遇到了一个例外:

Win32Exception: Fehler beim Erstellen des Fensterhandles 可以翻译为:

Win32Exception: Error while creating the windowhandle 我知道如何解决这个问题,甚至为此写了一篇短文——用德语

但我不知道我的应用程序可能会在哪里“泄漏”未处理的控件,这些控件仍然有窗口句柄

是否有任何方法可以检测/查找

实现IDisposable 具有父项==null
与此约束匹配的对象似乎是很好的候选对象。

每个实现IDisposable的对象都有一个Dispose方法。当不再需要对象时,应调用此方法。如果它仅在单个方法中使用,请使用using语句将其包围,并自动调用Dispose。如果它是类的成员变量,则类本身应该实现IDisposable。有一个检查规则。

任何合适的内存分析器都会向您显示控件实例。它们不会被垃圾收集,它们的句柄属性使它们保持活力。将有近10000个。您还可以使用任务管理器、使用查看+选择列和勾选用户对象来查看它。在测试应用程序时观察计数的增加应该会提供一个不错的提示

代码审查也应该走很长的路,没有那么多可能的方法泄漏窗口。首先查找最常见的情况,即调用Controls.Clear或Controls.Remove/At但不同时处理控件的代码。下一个常见情况是SystemEvents类,您必须显式取消订阅它的事件。其余的不容易找到,你需要那个分析器


通过反射,在运行时自己查找句柄在技术上是可能的。句柄存储在System.Internal.HandleCollector.handleTypes[]中。好的,从技术上讲。

如果没有收集它们是因为其他对象引用了您的控件,那么调用dispose或将parent设置为null都不够。也许你是在关注事件,而不是脱离它们


特别检查从附加程序未包含的控件附加到事件的情况,在这种情况下,在处理控件时应始终与事件分离,如果不分离,则附加程序仍将引用该控件,因此不会释放它

这是对完全不同问题的完美回答。他在问如何找到这些对象,因为很明显他有一些错误,他没有正确处理这些对象。FxCop至少可以找到其中的一些。它不是100%的命中率,但是比仅在单个方法中使用的0%控件更好的控件是毫无用处的。通常我喜欢在窗体上显示控件。我正在寻找一个运行时解决方案。反射也许可以做到,但我不知道怎么做。在我的情况下,应该是控制。清楚。。。如何访问System.Internal.HandleCollector.handleTypes[]?IDE抱怨没有System.Internal名称空间。这是我回答中技术上可能的条款。此字段标记为内部,在代码中无法访问。反射可以通过使用BindingFlags.NonPublic绕过此问题。使用内存分析器方法解决您的问题。如果您已经知道是控件。很明显,这导致了您的问题,那么在代码中找到它应该不会有任何问题。博客帖子链接已断开,但感谢achrive.org,它仍然可以访问