Hunting for window handles
I am working on a fairy large WinForms project and after a certain build our application suddenly started crashing. Click, click, boem... gone.... no exception, no event log entry, nothing. The annoying part was that this didn't happened while executing inside the debugger, only when the testers were clicking around inside the application and even then very undeterministically.
If you get problems like this the first thing to do is to attach a event handler to the Application.ThreadException event to try to figure out who is causing this error:
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Inside this event handler you can basically do diagnostics to find out what exception is being raised by looking at the ThreadExceptionEventArgs parameter.
So in this case the exception was "Error Creating Window Handle"... exactly the kind of exception that scares me. As Julia Lerman writes in a blog-post:
”Error Creating Window Handle” is a Win32 error, therefore the first thing I should have been looking at was any code that did anything with unmanaged items.
And it just so happened to be that one of the changes that we made to the application involved some GDI+ brushes and stuff like that. The first thing I did was making sure every brush and bitmap was disposed after being used by including them in the using pattern. Unfortunatly that alone didn't help much.
The specific part where we were using GDI+ drawing was inside a renderer for a given tabcontrol from a third party product that we are using in this application. Our application also needs to clear this tabcontrol and re-create all the tabs again quite often (for instance when the user navigates to a new area).
My huntch was that somehow every time this tabcontrol was refilled again the old tabs were still floating around somehwere in memory and not being garbage collected, it turned out that I was right... after changing the code from simply doing a:
leftTabControl.TabPages.Clear();
...to removing and disposing each individual item...
foreach (TabPage tab in leftTabControl.TabPages)
{
leftTabControl.TabPages.Remove(tab);
tab.Dispose();
}
...the problem went away.
Hope this helps.
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }