WinForms应用程序由于SystemEvents.OnUserPreferenceChanged事件而挂起 [英] WinForms application hang due to SystemEvents.OnUserPreferenceChanged event

查看:87
本文介绍了WinForms应用程序由于SystemEvents.OnUserPreferenceChanged事件而挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在处理客户端安装中挂起的一个奇怪的应用程序。
在尝试了几件事之后,我得出的结论是,没有转储将无法正常工作。
因此,我在闲暇时已经从一位客户那里得到了转储。
我必须注意,它仅发生在我的安装中,而不发生在我的开发计算机中。



在我的转储中,我看到SystemEvents.OnUserPreferenceChanged事件导致了我的UI线程来阻止等待线程,不再发送消息。



在这里和google中搜索后,我发现有些人也遇到了这个问题。
我在代码中上下移动,以查看是否有机会在非UI线程上创建了控件或窗体,但是没有运气。



这是我的!clrstack

  0012ee5c 7c90e514 [HelperMethodFrame_1OBJ:0012ee5c] 
System.Threading.WaitHandle.WaitOneNative(Microsoft .Win32.SafeHandles.SafeWaitHandle,UInt32,布尔值,布尔值)
0012ef08 792b68af System.Threading.WaitHandle.WaitOne(Int64,布尔值)
0012ef24 792b6865 System.Threading.WaitHandle.WaitOne(Int32,Boolean) b $ b 0012ef38 7b6f1a4f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012ef4c 7ba2d68b System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control,System.Delegate,System .Object [],布尔值)
0012efec 7b6f33ac System.Windows.Forms.Control.Invoke(System.Delegate,System.Object [])
0012f020 7b920bd7 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System .Threading.SendOrPostCallback,System.Object)
0012f 038 7a92ed62 Microsoft.Win32.SystemEvents + SystemEventInvokeInfo.Invoke(Boolean,System.Object [])
0012f06c 7a92dc8f Microsoft.Win32.SystemEvents.RaiseEvent(Boolean,System.Object,System.Object [])
0012f0b8 7a92e227 Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32,IntPtr,IntPtr)
0012f0d8 7aaa06ec Microsoft.Win32.SystemEvents.WindowProc(IntPtr,Int32,IntPtr,IntPtr)
0012f0dc [b] b $ b 0012f2a0 7b1d8d2e System.Windows.Forms.Application + ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32,Int32,Int32)
0012f33c 7b1d8997 System.Windows.Forms.Application + ThreadContext.RunMessageLoop (Int32,System.Windows.Forms.ApplicationContext)
0012f390 7b1d87e1 System.Windows.Forms.Application + ThreadContext.RunMessageLoop(Int32,System.Windows.Forms.ApplicationContext)
0012f3c0 7b195931 System.Windows.Forms .Application.Run(System.Windows.Forms.Form)
0012f3d4 034608b6 InsFocusBI.Presentation.MdiMain.NewMdiMainHandler(System.Object,NewSingleInstanceEventArgs)
0012f3ec 034607ac InsFocusBI.Utilities.SingleInstanceHandler.Start(System.String [],System.String)
0012f42c 0346021PreInsFocusBI。 Run(System.String [])
0012f440 0346019b InsFocusBI.Presentation.MdiMain.Main(System.String [])
0012f688 79e71b4c [GCFrame:0012f688]

我坚信也许通过转储,我可以弄清楚在另一个线程上创建的控件是什么,它将给我一个线索。 p>

我尝试!dso来获取所有堆栈对象:

  OS线程ID:0x4f0(0)
ESP / REG对象名称
0012ed90 0132e8cc System.Windows.Forms.WindowsFormsSynchronizationContext
0012ee1c 06bfe2a0 System.Threading.ManualResetEvent
0012ee30 06bfe2a0 System.Threading。 ManualResetEvent
0012ee9c 06bfe2a0 System.Threading.ManualResetEvent
0012eea4 0132381c System.Collection s.Hashtable
0012eeb0 06bfe2a0 System.Threading.ManualResetEvent
0012eee0 06bfe2b8 Microsoft.Win32.SafeHandles.SafeWaitHandle
0012ef28 06bfe2a0 System.Threading.ManualResetEvent
0012ef78.Windows.Form PropertyStore
0012ef80 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012ef88 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012ef8c 06bfe1b0 System.Windows.Forms.Control + ThreadMethodEntry
0012ef90 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012ef94 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012ef9c 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012efa4 06b4d018 System.Windows .Forms.Application + MarshalingControl
0012efd4 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012efe4 06bfe124 System.Object [](System.Object [])
0012efe8 06bfe104 System.Threading.SendOrPostCallback
0012efec 06bfe138 System.Windows.Forms .Control + MultithreadSafeCallScope
0012f004 064a8228 System.Threading.Thread
0012f00c 06b4d018 System.Windows.Forms.Application + MarshalingControl
0012f01c 06bfe124 System.Object [](System.Object [])
0012f028 06b4cf64 System.Windows.Forms.WindowsFormsSynchronizationContext
0012f034 06bfddc4 System.Object [](System.Object [])
0012f038 06b6096c Microsoft.Win32.SystemEvents + SystemEventInvokeInfo
0012f068 06bfddc4系统。 Object [](System.Object [])
0012f074 0132a174 System.Object
0012f078 06bfdde8 System.Object [](Microsoft.Win32.SystemEvents + SystemEventInvokeInfo [])
0012f07c 0132a298 System.Object
0012f0a4 0132a3c4 Microsoft.Win32.SystemEvents
0012f0a8 0132a298 System.Object
0012f0b4 06bfddc4 System.Object [](System.Object [])
0012f0c0 0132a3c4 Microsoft.Win32.SystemEvents $ b b $ b 0012f270 017dbd10 InsFocusBI.Presentation.Controls.CustomListView
0012f288 0132e8f0 System.Windows.Forms.Application + ThreadContext
0012f2cc 017860c0 System.Windows.Forms.NativeMethods + MSG []
0012f2d0 0132e8f0 System.Windows.Forms.Application + ThreadContext
0012f2d8 01372050 System.Windows.Forms.Application + ComponentManager
0012f350 0132e8f0 System.Windows.Forms.Application + ThreadContext
0012f38c 01785a74 System.Windows.Forms.ApplicationContext
0012f428 012fd464 System.String el02
0012f6f4 012f913c System.Object [](System.String [])

我唯一看到的是InsFocusBI.Presentation.Controls.CustomListView,但我没有看到它是在另一个线程上创建的。



有什么建议吗?有人可以给另一个想法或尝试的东西吗?



谢谢

解决方案

嗯,您在非UI线程上遇到了控件创建的经典问题。




  • 可能是您正在创建控件。 / li>
  • 对某些属性的访问会在您不知道的情况下(很少)创建一个控件。

  • 在创建属性之前访问Handle属性(可能是间接的) )。

  • 由InvokeRequired(参考1),(参考2)欺骗。



太好了请阅读以下主题:(ref 1)(ref 2)和(ref 3)。



我不知道在转储中找到控件的方法(
,但您可以尝试按(ref 4)和(ref 5)中所述在代码中设置断点。



干杯。



参考:


  1. 神秘的吊灯或Inv的大骗局okeRequired


  2. Control.Trifecta:InvokeRequired,IsHandleCreated和IsDisposed


  3. 。NET 2.0 WinForms多线程和漫长的几天


  4. 调试UI


  5. 泄漏线程句柄的情况



I've been dealing with a strange application hang in my clients installations. After trying several things i reached the conclusion that without a dump it won't work. So I've taken a dump from one of my clients at the hang time. I must note that it only happens in my installations and not in my development computers.

In my dump I see that the SystemEvents.OnUserPreferenceChanged event causes my UI thread to block waiting for a thread, that is no longer pumping messages.

After searching here and in google, I found that some people we're having that issue as well. I went up and down my code looking to see if by any chance we created a control or a form on a non UI thread, but with no luck.

This is my !clrstack

 0012ee5c 7c90e514 [HelperMethodFrame_1OBJ: 0012ee5c] 
System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
0012ef08 792b68af System.Threading.WaitHandle.WaitOne(Int64, Boolean)
0012ef24 792b6865 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
0012ef38 7b6f1a4f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012ef4c 7ba2d68b System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)
0012efec 7b6f33ac System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])
0012f020 7b920bd7 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)
0012f038 7a92ed62 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])
0012f06c 7a92dc8f Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])
0012f0b8 7a92e227 Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32, IntPtr, IntPtr)
0012f0d8 7aaa06ec Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)
0012f0dc 003c222c [InlinedCallFrame: 0012f0dc] 
0012f2a0 7b1d8d2e System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0012f33c 7b1d8997 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0012f390 7b1d87e1 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0012f3c0 7b195931 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
0012f3d4 034608b6 InsFocusBI.Presentation.MdiMain.NewMdiMainHandler(System.Object, NewSingleInstanceEventArgs)
0012f3ec 034607ac InsFocusBI.Utilities.SingleInstanceHandler.Start(System.String[], System.String)
0012f42c 0346021a InsFocusBI.Presentation.MdiMain.Run(System.String[])
0012f440 0346019b InsFocusBI.Presentation.MdiMain.Main(System.String[])
0012f688 79e71b4c [GCFrame: 0012f688] 

I tought that maybe using the dump i can figure out what is the control that was created on the other thread and it would give me a clue.

I tried !dso to get all of the stack objects:

OS Thread Id: 0x4f0 (0)
ESP/REG  Object   Name
0012ed90 0132e8cc System.Windows.Forms.WindowsFormsSynchronizationContext
0012ee1c 06bfe2a0 System.Threading.ManualResetEvent
0012ee30 06bfe2a0 System.Threading.ManualResetEvent
0012ee9c 06bfe2a0 System.Threading.ManualResetEvent
0012eea4 0132381c System.Collections.Hashtable
0012eeb0 06bfe2a0 System.Threading.ManualResetEvent
0012eee0 06bfe2b8 Microsoft.Win32.SafeHandles.SafeWaitHandle
0012ef28 06bfe2a0 System.Threading.ManualResetEvent
0012ef78 06b4d080 System.Windows.Forms.PropertyStore
0012ef80 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012ef88 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012ef8c 06bfe1b0 System.Windows.Forms.Control+ThreadMethodEntry
0012ef90 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012ef94 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012ef9c 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012efa4 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012efd4 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012efe4 06bfe124 System.Object[]    (System.Object[])
0012efe8 06bfe104 System.Threading.SendOrPostCallback
0012efec 06bfe138 System.Windows.Forms.Control+MultithreadSafeCallScope
0012f004 064a8228 System.Threading.Thread
0012f00c 06b4d018 System.Windows.Forms.Application+MarshalingControl
0012f01c 06bfe124 System.Object[]    (System.Object[])
0012f028 06b4cf64 System.Windows.Forms.WindowsFormsSynchronizationContext
0012f034 06bfddc4 System.Object[]    (System.Object[])
0012f038 06b6096c Microsoft.Win32.SystemEvents+SystemEventInvokeInfo
0012f068 06bfddc4 System.Object[]    (System.Object[])
0012f074 0132a174 System.Object
0012f078 06bfdde8 System.Object[]    (Microsoft.Win32.SystemEvents+SystemEventInvokeInfo[])
0012f07c 0132a298 System.Object
0012f0a4 0132a3c4 Microsoft.Win32.SystemEvents
0012f0a8 0132a298 System.Object
0012f0b4 06bfddc4 System.Object[]    (System.Object[])
0012f0c0 0132a3c4 Microsoft.Win32.SystemEvents
0012f270 017dbd10 InsFocusBI.Presentation.Controls.CustomListView
0012f288 0132e8f0 System.Windows.Forms.Application+ThreadContext
0012f2cc 017860c0 System.Windows.Forms.NativeMethods+MSG[]
0012f2d0 0132e8f0 System.Windows.Forms.Application+ThreadContext
0012f2d8 01372050 System.Windows.Forms.Application+ComponentManager
0012f350 0132e8f0 System.Windows.Forms.Application+ThreadContext
0012f38c 01785a74 System.Windows.Forms.ApplicationContext
0012f428 012fd464 System.String    el02
0012f6f4 012f913c System.Object[]    (System.String[])

The only thing i see is InsFocusBI.Presentation.Controls.CustomListView but i don't see that it is created on another thread.

Any advice? can someone give another idea or something to try?

Thanks

解决方案

Well, you have thee classic problem of control 'creation' on non UI thread.

  • It may be you are creating the control.
  • Access to some property creates a control underneath without you knowing (rare).
  • Access to the Handle property before it is been created (may be indirectly).
  • Fooled by InvokeRequired (ref 1), (ref 2).

Great read on the subject: (ref 1) (ref 2) and (ref 3).

I don't know of a way to find the control in a dump (tried myself) but you can try to set a breakpoint in code as described in (ref 4) and (ref 5).

Cheers.

Reference:

  1. Mysterious Hang or The Great Deception of InvokeRequired

  2. Control.Trifecta: InvokeRequired, IsHandleCreated, and IsDisposed

  3. .NET 2.0 WinForms multithreading and a few long days

  4. Debugging UI

  5. The case of the leaking thread handles

这篇关于WinForms应用程序由于SystemEvents.OnUserPreferenceChanged事件而挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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