Windows Forms and Threading

A number of people have asked me about accessing Windows Forms controls and their associated events, properties, and methods using an external thread, a different language in the same application, or an external application. These are three completely different situations, but they all have one thing in common—it generally isn’t a good idea to access Windows Forms controls external to the thread that creates them because you encounter all sorts of threading problems. Windows Forms controls aren’t inherently thread safe. If two different threads were to try to access the control at the same time, you could force the control into an inconsistent state and your application would crash—if you’re lucky. If you aren’t so lucky, then you might experience other kinds of problems, including data loss.

Of course, you do encounter situations where you need to access the controls externally. In fact, there is a Microsoft sanctioned protocol for doing so and you can read about it in, “How to: Make Thread-Safe Calls to Windows Forms Controls.” Using this approach is time consuming, error prone, and requires a lot more code than simply keeping your application clean of external thread calls whenever possible. However, it does work reliably—at least, most of the time. Some developers still encounter problems, especially when debugging the application. The solution, in many cases, is to set the CheckForIllegalCrossThreadCalls property to false. Unfortunately, setting this property to false simply turns off the alarm that is telling you that something has gone wrong—it doesn’t fix the underlying problem. Often, the developer hasn’t dotted an i or crossed a t in the somewhat complicated code required to perform this task. If you want to see this technique in action, try out the example shown at, “How to: Use a Background Thread to Search for Files” (various versions  of the same example exist, so make sure you download the version for your setup). A wealth of other examples exists online to demonstrate variations on this technique, but you must proceed with caution because finding a bug in your code is incredibly hard.

There is another way to affect the controls in a form and I’ve used it reliably on a number of situations. Ultimately, any application you create relies on the Win32 API—at least, if you’re using Windows 7 and older. In this case, you have the option of ignoring .NET altogether and interacting with the form outside of the .NET environment. There is even less documentation on this technique, but it also works reliably if you’re careful when creating your application. I documented this approach in a series of four articles that I discuss in my Working with Low Level Code post. In this case, you can access the form and its controls even if you don’t have the application source code (and the technique works equally well with managed and native code applications). In addition, you can do it without using a .NET language. The only requirement is that the language you choose be able to work with the Win32 API. In addition, you must get used to the idea of working with the Windows messaging system, rather than directly with events.

Eventually, new programming strategies will replace the existing Windows Forms approach to creating applications. Older versions of Windows will give way to newer products that allow multithreaded access to controls. Until that happens, keeping your code as clean as possible is an important part of the strategy for making applications robust and error free. Before you decide to access a control from another thread (no matter where that other thread might reside) consider revamping your code so that the access isn’t necessary. Let me know your thoughts on multithreaded control access at John@JohnMuellerBooks.com.