RAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION.
A Windows Forms application's UI may freeze if system settings are changed or the workstation is locked and unlocked.
The application will not respond and the UI thread will hang in an Invoke call while handling the OnUserPreferenceChanged notification:
This occurs if a control is created on a thread which doesn't pump messages and the UI thread receives a WM_SETTINGCHANGE message.
All top level controls register for the SystemEvents.UserPreferenceChanged event so that they can be notified of system wide setting changes such as color, theme, desktop size, etc. The SystemEvents system listens for this message, and when it receives the messages it fires the UserPreferenceChanged notification for all of the objects which have registered to receive that message. SystemEvents checks if the registered object is on its own thread, and if not it Invokes to the object's thread so that the notification will fire in the correct context.
The problem occurs if the object's thread does not pump messages, since the Invoke method relies on window messages. Invoke posts a message with the delegate data and then waits until the message has been received and handled. If the target thread doesn't pump messages, then the posted message never gets handled, and Invoke waits forever.
Common causes are a splash screens created on a secondary UI thread or any controls created on worker threads.
Applications should never leave Control objects on threads without an active message pump. If Controls cannot be created on the main UI thread, they should be created on a dedicated secondary UI thread and Disposed as soon as they are no longer needed.
One way to identify which windows are created on which thread is with Spy++ in the Processes view (Spy.Processes menu). Select the hung process and expand its threads to see if there are any unexpected windows. This will find the native window if it still exists; however, the problem can occur even if the native window has been destroyed, so long as the managed Control has not yet been Disposed.
MICROSOFT CORPORATION AND/OR ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY, RELIABILITY, OR ACCURACY OF THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN. ALL SUCH INFORMATION AND RELATED GRAPHICS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT AND/OR ITS RESPECTIVE SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THIS INFORMATION AND RELATED GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE EFFORT, TITLE AND NON-INFRINGEMENT. YOU SPECIFICALLY AGREE THAT IN NO EVENT SHALL MICROSOFT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, INCIDENTAL, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT OF OR IN ANY WAY CONNECTED WITH THE USE OF OR INABILITY TO USE THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF MICROSOFT OR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES.