I spent some time late last work working with my colleague Jeff Berkowitz on what seemed like a pretty sticky problem. He’s got some more info about the problem here, but the quick description is that we were in a situation where Control.InvokeRequired was apparently returning an incorrect value. Our code was clearly running on a thread other than the GUI thread, and yet InvokeRequired returned false. Disconcerting to say the least.
Jeff spent quite a bit of time tracking down the problem over the weekend, and the conclusion that he came to is that if you want to call Control.InvokeRequired and get a rational and deterministic answer, the control you are calling it on must be embedded in the control containment hierarchy all the way up to a top level Form. What we were doing involved creating controls but holding them in memory without putting them into the “visual” hierarchy of the application, meaning that they were not contained by a parent Control or Form. Apparently if that is the case, InvokeRequired doesn’t return the correct results. (Note that so far this is based on experiential evidence and not “scientific” data.)
The longer I think about this the more I’m not surprised that this is the case, but I’ve never seen any hint of documentation (from MS or otherwise) that indicates that this is true. The solution (at least for us) is pretty straightforward, and involved moving some initialization code until after all the controls have been fully created and sited in forms. Not a big deal, but it does prevent us from doing some up front initialization in a place where our users wouldn’t notice it. Now it’ll take a progress dialog. Seems like a reasonable price to pay, but it would, of course, be nicer if it worked the way we expected it to.