2008
12.12

Recently I wanted to show a splash screen form in an application, loading the image file from the disk at run time instead of binding it into the executable. It’s easy enough to load the image with Image.FromFile, but if the file is not there, I wanted to fail gracefully and just close the form.
When I called Close() from the FormLoad event, however, the following exception greeted me: Value Close() cannot be called while doing CreateHandle().
What does that mean?
A little searching around coupled with my experience in traditional Windows programming led me to conclude that the .NET runtime doesn’t like to have it’s forms closed while they are being created. In the C++ days, we would just PostMessage with WM_CLOSE to the hWnd, and all would be well. Hmmm… What to do in C#?
In searching, I ran across the BeginInvoke method, which “Executes a delegate asynchronously on the thread that the control’s underlying handle was created on.” Sounds interesting.
What delegate to use, however, was the next question. MethodInvoker is the answer. According to the Microsoft docs, MethodInvoker “represents a delegate that can execute any method in managed code that is declared void and takes no parameters.” The intended use is for “when you need a simple delegate but do not want to define one yourself.” Exactly what I was looking for.
So I defined a simple function in my form class that would be used by the delegate:

private void CloseMe()
{
  Close();
}

In the CloseMe method, I simply do what I wanted to do in the first place – call Close() on the form.  Close() is now safe to call because we are no longer in the FormLoad event.

From the FormLoad event, if the image file was not found, simply call the asynchronous BeginInvoke method:

void FormLoad(object sender, EventArgs e)
{
  if(imageNotFound)
  {
    BeginInvoke(new MethodInvoker(CloseMe));
  }
}

It works great and no more exception!
midniteblogger