I have a window form application, and it has multiple threads running that would invoke on the Main UI thread to update the UI. Occasionally on development machine, the app
Yes, this is a fairly infamous threading problem caused by the SystemEvents class. I never got a solid diagnostic for it but the 90% odds are that this is triggered by an initialization problem in your app.
The root problem is that SystemEvents gets initialized on-demand by the first form in your app that has controls that are interested in the events it generates. If that first form is not created in the main thread then SystemEvents is helpless to guess at which thread is the UI thread in your program. Eventually, when a notification is received (like UserPreferenceChanging), it tries to fire the event on that thread, but it isn't around anymore. The fallback code in the SynchronizationContext class raises the event on a threadpool thread instead. That inevitably invokes Threading Hell by running UI code on a thread that didn't create the window. Lots of things can go wrong when that happens. Deadlock is a particularly common outcome when restoring the desktop after the workstation was locked.
Not the only possible way this can go wrong, it is inevitable if you create any form on another thread. Now SystemEvents cannot possibly raise the event on the correct thread of course, somebody is going to lose. A blog post that demonstrates a debugging technique is here. Yes, ugly. Ideally a control knows to deal with this and marshal the notification itself. But that was forgotten knowledge at .NET 2.0, DataGridView, NumericUpDown, DomainUpDown, ToolStrip+MenuStrip and the ToolStripItem derived classes don't do this. I should note that RichTextBox and ProgressBar are suspicious, the rest are okay.
Review the startup sequence of your app. Creating your own splash screen is a good lead, do favor using the built-in support that the WindowsFormsApplicationBase class provides. If you do it yourself then keep it very simple, just a bitmap. And as noted, any place where you might create your own form on a worker thread is a recipe for trouble. Always do it the other way around, run the expensive code on a worker and keep the UI on the main thread.