tags:

views:

113

answers:

3

I ran into this exception yesterday:

Win32Exception: Fehler beim Erstellen des Fensterhandles

might translate:

Win32Exception: Error while creating the windowhandle

I know how to solve this (even wrote a short blog post on the topic - in german)

But I don't know where my application might be 'leaking' not disposed Controls, that still have window-handles.

Is there any way of detecting / finding instances that

  • implement IDisposable
  • have Parent == null

Objects matching this constraints seem to be good candidates.

A: 

Every object which implements IDisposable has a Dispose method. This method should be called when the object is no longer needed. Is it used in a single method only, surround it with a using statement (calls Dispose automatically). If it is a member variable of your class, your class should implement IDisposable itself. FxCop has a check rule for this.

Scoregraphic
Perfectly good answer to quite a different question. He's asking how to *find* those objects, because obviously he has some bugs where he's not disposing of the objects correctly.
Lasse V. Karlsen
FxCop could find at least some of them. It's not a 100% hit ratio, but better than 0%
Scoregraphic
Controls that are used in a single method only are quite useless. Normally I like my controls displayed on an form. I'm looking for a runtime solution. Reflection might do it, but i don't know how.
Simon Ottenhaus
+1  A: 

Any decent memory profiler will show you the control instances. They won't be garbage collected, their Handle property keeps them alive. There will be close to 10,000 of them.

A code review ought to go a long way too, there are not that many possible ways to leak a window. Look for code that calls Controls.Remove() but don't explicitly dispose the control. Or a form displayed with ShowDialog() that doesn't get disposed and forgets to unregister a static event handler (SystemEvents e.g.)

Finding the handles yourself at runtime is technically possible with Reflection. The handles are stored in System.Internal.HandleCollector.handleTypes[]. Well, technically.

Hans Passant
In my case it would be Controls.Clear() ... How do I access System.Internal.HandleCollector.handleTypes[] ? The IDE complains that there is no System.Internal namespace.
Simon Ottenhaus
That's the "technically possible" clause in my answer. This field is marked internal, it is not accessible in your code. Reflection can bypass this by using BindingFlags.NonPublic. Chase the memory profiler approach to solving your problem. If you already know that it is Controls.Clear() that causes your problem then you shouldn't have any trouble finding it back in your code.
Hans Passant
A: 

If they are not collected is because some other object is referencing your controls, neither calling dispose nor setting parent to null is enough. Maybe you are attaching to events and not dettaching from them.

Check specially the case of attaching to events from controls not being contained by the attacher, in this case you should always detach from the events when disposing the controls, if not the control will still continue to be referenced by the attacher and thus it will not be released

jmservera