Wednesday, November 16, 2005

How to invoke a method AFTER an event handler in .Net

BeginInvoke! There's a magic word for you. It sounds like black magic but works like a charm. It's nothing new, but it stayed hidden in the multithreaded realm and I've avoided it for long although it popped up every now and then to save the day.

Specifically I'm talking of .Net windows forms programming, and the Control.BeginInvoke() method. The MSDN library says that BeginInvoke is used to execute a call asynchronously on the form's primary thread: big deal. The real stuff is hidden behind the word "asynchronously"...

What happens if you call BeginInvoke ON the primary thread? The call is just queued in some kind of a request queue (it's the good old message queue). The form will finish the event handler that it's currently executing and then call our method!

So: inside an event handler you decide you want to do something after the handler finishes? No problem, just BeginInvoke() the method that does your stuff. Here's two illustrations that spring to mind:

- Focusing a (grand)child control from within the form's Load (OnLoad) event won't work because the CanFocus property of the control is false (it's initialization hasn't finished yet? Whatever). Use BeginInvoke() to execute your method AFTER OnLoad.

- Changing the contents of a ListView from within an ItemCheck event handler (probably true for any other event). If you try to add items to the list, it will go mad. Just schedule your method for later with BeginInvoke().