如何处理C#挂起SystemEvents.OnUserPreferenceChanged [英] How to deal with this C# hang invloving SystemEvents.OnUserPreferenceChanged

查看:91
本文介绍了如何处理C#挂起SystemEvents.OnUserPreferenceChanged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的WinForm应用程序出现挂起问题.发生的情况是,客户端有时会使应用程序整夜运行,而当它们早晨恢复时通常处于挂起状态.这是我在主线程上的转储文件中看到的.我不了解是什么使SystemEvents.OnUserPreferenceChanged事件被调用,尽管我认为我没有做任何事情来调用此事件.

My WinForm application having a hang problem. What happen is that client sometime leave the application running overnight and when they comeback in morning application is typically in a hang state. This is what I see in dump file on the main thread. What I don't understand is what could make SystemEvents.OnUserPreferenceChanged event to be invoked, although I don't think I am doing anything that is invoking this event.

0024e480 770496f4 System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)  
0024e52c 702c68af System.Threading.WaitHandle.WaitOne(Int64, Boolean)  
0024e548 702c6865 System.Threading.WaitHandle.WaitOne(Int32, Boolean)  
0024e55c 6e891a6f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)  
0024e570 6ebcd6eb System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)  
0024e610 6e8933cc System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])  
0024e644 6eac0c83 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)  
0024e65c 6fe1eed2 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])  
0024e690 6fe1d07f Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])  
0024e6dc 6fe1e38f Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32, IntPtr, IntPtr)  
0024e6fc 6fa64c29 Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)  
0024e700 000a1104 [InlinedCallFrame: 0024e700]   
0024e8d8 6e378d5e System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)  
0024e974 6e3789c7 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)  
0024e9c8 6e378811 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)  
0024e9f8 6e88de47 System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form)  
0024ea0c 6e8c25cb System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)  
0024ea98 6e8c27e3 System.Windows.Forms.Form.ShowDialog()  
0024ea9c 56c26e76 MyNameSpace.MyForm.MyMethod2(Object, Boolean, Boolean, System.Guid, Boolean)  
0024eba0 56c26c47 MyNameSpace.MyForm.MyMethod1(System.Guid, System.Guid, System.Guid, Boolean)  
0024ecf8 56c91f4c MyNameSpace.MyForm.MyButton_Click(System.Object, System.EventArgs)  
0024ee88 6e334180 System.Windows.Forms.Control.OnClick(System.EventArgs)  

推荐答案

控件订阅此事件,以便在用户更改主题或系统颜色时它们将重绘自己.当您不靠近计算机并且Windows自动锁定工作站时,也会触发此事件.解释了宿醉后的早晨.

Controls subscribe this event so that they will redraw themselves when the user changed the theme or system colors. This event also gets fired when you're not close to the machine and Windows automatically locks the workstation. Which explains the morning-after hangover.

死锁是由线程问题引起的,SystemEvents类在错误的线程上触发事件.这是由程序中的初始化问题引起的.典型的触发器不是在主线程上创建第一个窗口,该窗口使SystemEvents感到困惑.它尝试再次在同一线程上触发事件,但不再存在.或者,它在Winforms初始化之前复制了SynchronizationContext.Current.无论哪种方式,事件都将在线程池线程而不是主UI线程上触发.致命的.

The deadlock is caused by a threading problem, the SystemEvents class fires the event on the wrong thread. Which is caused by an initialization problem in your program. The typical trigger is not creating the first window on the main thread, that confuzzles SystemEvents. It tries to fire an event on that same thread again but it isn't around anymore. Or it copied SynchronizationContext.Current before it got initialized by Winforms. Either way, the event will fire on a threadpool thread instead of the main UI thread. That's lethal.

例如,当您实现自己的启动屏幕时,常见.改为使用内置支持.

Common when you implement your own splash screen for example. Use the built-in support instead.

这篇关于如何处理C#挂起SystemEvents.OnUserPreferenceChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆