Detect windowhandle leaks in a c# application
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 stil开发者_Python百科l 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.
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. You can also see it with Task Manager, use View + Select Columns and tick USER Objects. Watching the count increase as you are testing the app should provide a decent hint.
A code review ought to go a long way too, there are not that many possible ways to leak a window. First look for the most common case, code that calls Controls.Clear() or Controls.Remove/At() but does not also dispose the control. Next common case is the SystemEvents class, you have to explicitly unsubscribe its events. The rest are not so easy to find, you'd need that profiler.
Finding the handles yourself at runtime is technically possible with Reflection. The handles are stored in System.Internal.HandleCollector.handleTypes[]. Well, technically.
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.
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
精彩评论