代码之家  ›  专栏  ›  技术社区  ›  Simon Ottenhaus

检测C应用程序中的WindowHandle泄漏

  •  2
  • Simon Ottenhaus  · 技术社区  · 16 年前

    昨天我遇到了一个例外:

    Win32Exception: Fehler beim Erstellen des Fensterhandles

    可能会翻译:

    Win32Exception: Error while creating the windowhandle

    我知道如何解决这个问题(甚至写了一个简短的 blog post 关于这个话题-德语)

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

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

    • 实施 IDisposable
    • Parent == null

    与此约束匹配的对象似乎是很好的候选者。

    3 回复  |  直到 11 年前
        1
  •  2
  •   Hans Passant    11 年前

    任何合适的内存探查器都将向您显示控制实例。它们不会被垃圾收集,它们的手柄属性使它们能够存活。其中将有近10000个。您还可以使用任务管理器查看它,使用视图+选择列并勾选用户对象。在测试应用程序时观察计数的增加应该会提供一个不错的提示。

    代码审查也应该有很长的路要走,没有那么多可能的方法来泄漏一个窗口。首先查找最常见的情况,即调用controls.clear()或controls.remove/at()但不处理该控件的代码。下一个常见的情况是SystemEvents类,您必须显式取消订阅它的事件。剩下的不太容易找到,你需要那个剖析器。

    在运行时找到自己的句柄在技术上是可以通过反射实现的。句柄存储在System.Internal.HandleCollector.HandleTypes[]中。从技术上讲。

        2
  •  0
  •   Scoregraphic    16 年前

    实现的每个对象 IDisposable 有一个 Dispose 方法。当不再需要对象时,应调用此方法。是否仅在单个方法中使用,并用 using 语句(调用 处置 自动)。如果它是类的成员变量,则类应实现 可识别 本身。 FxCop 对此有一个检查规则。

        3
  •  0
  •   jmservera    16 年前

    如果未收集它们是因为其他某个对象正在引用您的控件,那么调用Dispose或将Parent设置为空都是不够的。也许你是在关注事件,而不是脱离它们。

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