Sometimes people don’t even read what they’re typing


As an even more extreme case of people seeing something, confirming that they see it, but not actually reading it is someone who sees something, types it into an email message, yet still doesn't read it.

Subject: "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." exception crashes our program

I'm looking for guidance on why this exception is thrown and how I can avoid it. Here's a sketch of what we're doing:

void DoStuff() {                                                              
  try {                
    // attempt operation X, which throws an exception when it fails
  } catch {                
    this.BeginInvoke(new ShowErrorDelegate(this.OnShowError), null);
  }
}

If operation X fails, the catch clause runs, but it throws the exception "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." Why is it happening? It's crashing our program. Right now, we're working around it by wrapping the BeginInvoke inside its own try/catch, but we'd like to understand why the exception is occurring in the first place and how we can avoid it.

Now, I don't know much about WinForms, so I could be way off base here, but perhaps the problem is that you're calling BeginInvoke on a control before its window handle has been created. I'm just basing that on the text that you typed into the subject line and again into the message text. The workaround therefore is to make sure the window handle has been created before calling BeginInvoke. (You can imagine any number of ways of ensuring this.)

Though I do admire the approach of "We don't know what's going on, so we'll just wrap it inside an exception handler and pretend it didn't happen."

Comments (20)
  1. SuperKoko says:

    We don’t know what’s going on, so we’ll just wrap it inside an exception handler and pretend it didn’t happen.

    It reminds me guys who want to validate their strict HTML.

    target=_blank is invalid in the strict DTD, so they wrap it in a javascript link. Since validators don’t read javascripts, they don’t notice that!

  2. Karellen says:

    I suspect that the question actually being asked here is "What is a window handle, why does a mere control need one, why isn’t it created for me when I create the control, and what do I have to do/wait for for the window handle to be created?"

  3. Caliban Darklock says:

    There are two problems here of different priorities.

    Problem 1: We are getting an exception and we don’t know why.

    Problem 2: The exception is crashing the program.

    From a business perspective, problem 2 is more important than problem 1. While the developer wants problem 1 solved, which will naturally make problem 2 go away, that will take time (for example, one must wait for Raymond to read and respond to the email).

    In the meanwhile, by any means necessary, stop the program from crashing – this makes it LESS of a problem to a businessman who may be demonstrating the program to a potential client. The client may buy a program which has a few quirks like you click a button and nothing happens. The client is far less likely to buy a program which crashes.

    So you wrap the exception in a try/catch and ignore it. The underlying problem has not changed, but the program stops crashing.

  4. Tone says:

    Similar experience with my brother-in-law who accused me of messing up his new game. After he let me play it he recieved an error and it was, of course, my fault.

    Error: Game disc not in disc drive. Insert disc and try again.

    My bad.

  5. @Caliban

    ‘So you wrap the exception in a try/catch and ignore it. The underlying problem has not changed, but the program stops crashing.’

    And then the try/catch is left in and masks a bunch of other problems, even after you solve the original problem.

  6. reader says:

    I have a feeling the (unspoken) problem is that the developer expects the control to already have a window handle at the point when the issue occurs.  Perhaps the real question is "why doesn’t the control have a window handle yet?"  Not that this is any excuse for not phrasing the question correctly.

  7. Ian Boyd says:

    i can’t really blame someone for not understanding Windows handles in .NET programming. The fact that some controls use things called "window handles" when running on Windows is an implementation detail, that leaks out now and again.

    Nothing says that some future version of the the .NET library won’t use controls that are not simply thin wrappers around a Windows common control. In 50 years the ListView control might not be a Win32 listview, and Windows might not even use HWNDs.

    But yes, his question should have been: "I’m getting this exception, telling me that a control doesn’t have a window handle assigned. What is a window handle? How do i assign it? When should i assign it? What is the reason it should be assigned? What technique should i be using that doesn’t require it to be assigned? What is the downside of assigning a window handle?" etc…

  8. BryanWolf says:

    Yeah, this is definitely a scenario where inability to google + obscure error message = oddly phrased bad question.

    In this case, if you tried to solve the actual error message you would probably shoot yourself in the foot.  9 times out of 10, the issue is that you’re attempting to access a control from a thread other than the one on which it was created.

    I just did a google search to see what would come up and the top result is an MSDN forums result where the correct answer is posted.

  9. Tone: I had that, years ago, after borrowing a secretary’s system to use her label printer. Being sensible, I turned the PC and printer off when finished with them, only to be blamed some days later when she encountered an error from the label printer application. The error, of course, resulted from the printer being switched off: apparently she had never switched it off before, so never switched it on either.

  10. It could be worse. Java’s compile-time checked exceptions are a great feature but some people seem to take compile errors as a personal challenge.

    I have seen production Java code that extensively used a subclass of the File class which provided no new functionality but silently swallowed exceptions so the rest of the code didn’t have to worry about those pesky compile errors.

  11. ton says:

    Just pathetic, *all* the information is clearly stated but yet the user(developer?) still cries foul. Again there are some folks who really shouldn’t be programming.

  12. This can also happen if they instance a Form and try to do stuff to it before they’ve actually shown it, since the Handle is lazily initialized. If showing the form isn’t feasible, simply accessing the Handle property of the form (IntPtr hwnd = myForm.Handle;) will usually do the trick. Or just doing the work in the HandleCreated event. I’ve also seen it come up when someone instances a Form in their UI thread but tries to show the form in the background thread–then InvokeRequired stops working properly.

    But yeah — it’s not like the exception is particularly unclear or anything.

    Reminds me of our international customers who call and complain about getting charged a VAT tax despite having clicked a checkbox to confirm they’ve read a huge "YOU MAY BE CHARGED A VAT TAX BY YOUR COUNTRY" tax notice during checkout.

    People just don’t read things. Simple as that.

  13. Karellen says:

    "In 50 years the [.NET] ListView control might not be a Win32 listview"

    Well, that might be the case /right now/, if you’re running your .NET app on the Mono implementation of .NET on Linux.

  14. Tsukrov says:

    I used to dislike .NET for that.

    Yup, I know it packs the params and send them via PostMessage. Sure.

    But could it work other way, "free-threaded"?

    Can I change my GUI from other thread painless?

    Could .NET take the work?

  15. My favorite part of this problem is that if they add the simple check to see if the handle is created (for instance, by checking the .Handle property), they will actually prompt the creation of the window (and associated handle) simply by trying to see if it’s been created.

    I call it Brandon’s Certainty Principle of WinForms window handles.  If you check it, it’s pretty much guaranteed to be there.  But if you don’t, it might not be :)

  16. chrismcb says:

    I don’t understand their work around.

    Starting something up fails because of some unknown error.

    So the workaround is to ignore the failure of the thing being started up? How did this solve anything, other than stopping the crash?

    Shoot, deleting the line of code would have done the same thing.

  17. Drak says:

    This sort of reminds me of error reports we sometimes get from clients. They attach the error message to the report. It says ‘There is not enough space on drive C:’.

    The client asks us if we can fix his problem. Time taken: 1 or 2 days depending on how busy our service desk is with other things. If the client had read the error message he could have fixed it himself in 5 minutes.

  18. J says:

    "So the workaround is to ignore the failure of the thing being started up? How did this solve anything, other than stopping the crash?"

    Maybe they were trying to use it at some point before everything was initialized, and then once everything was initialized, it worked as intended.  So by eating the exception, they got past the initialization crash long enough for everything to start working.

    Same kind of issue if you have a global object instance whose constructor runs before main() and the constructor calls into some framework that hasn’t been initialized yet.  And you’re expecting main() to run first because it calls GenericFrameworkInitialize() before kicking off your threads and whatever.

  19. Brian says:

    WPF doesn’t use the win32 listview or handles for it’s controls either (a Window being the exception, of course), so you don’t have wait 50 years. :)

  20. chrismcb says:

    @J I still don’t get it.

    "Maybe they were trying to use it at some point before everything was initialized, and then once everything was initialized, it worked as intended."

    So you are saying this thing is called twice? The first time they eat the exception, the second time it works. SO, if things were different and the exception doesn’t get fired, that means they’ll do a BeginInvoke twice?

    Maybe they are just getting lucky and it is always the case that the first try throws an exception, and the second succeeds. But I hate to program by luck.

Comments are closed.

Skip to main content