PeekMessage是否分发WM_SHOW消息?.NET应用重入问题咨询
.NET WinForms应用PeekMessage消息分发与锁重入问题
异常堆栈跟踪
我开发的大型.NET WinForms应用出现锁重入相关异常,托管代码堆栈跟踪如下:
System.Windows.Forms.Control.OnParentVisibleChanged(System.EventArgs) System.Windows.Forms.Control.OnVisibleChanged(System.EventArgs) System.Windows.Forms.Control.WmShowWindow(System.Windows.Forms.Message ByRef) System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef) System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr) DomainBoundILStubClass.IL_STUB_ReversePInvoke(Int64, Int32, Int64, Int64) MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr, IntPtr, Int32, IntPtr, IntPtr) MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr) System.Threading.Monitor.Enter(System.Object)
Win32原生堆栈信息
对应的Win32原生堆栈如下:
System_Windows_Forms_ni+0x9e89d2 clr!UMThunkStub+0x6e user32!UserCallWinProcCheckWow+0x2f8 user32!CallWindowProcW+0x8e WindowsBase_ni+0x1632e2 WindowsBase_ni+0x323e42 clr!UMThunkStub+0x6e user32!UserCallWinProcCheckWow+0x2f8 user32!DispatchClientMessage+0x9c user32!_fnDWORD+0x33 ntdll!KiUserCallbackDispatcherContinue win32u!NtUserPeekMessage+0x14 user32!_PeekMessage+0x43 user32!PeekMessageW+0x143 combase!CCliModalLoop::MyPeekMessage+0x53 [onecore\com\combase\dcomrem\callctrl.cxx @ 2925] combase!CCliModalLoop::PeekRPCAndDDEMessage+0x49 [onecore\com\combase\dcomrem\callctrl.cxx @ 2607] combase!CCliModalLoop::BlockFn+0x2c5 [onecore\com\combase\dcomrem\callctrl.cxx @ 2103] combase!ClassicSTAThreadWaitForHandles+0xa5 [onecore\com\combase\dcomrem\classicsta.cpp @ 51] combase!CoWaitForMultipleHandles+0x76 [onecore\com\combase\dcomrem\sync.cxx @ 123] clr!MsgWaitHelper+0x8e clr!Thread::DoAppropriateWaitWorker+0x2e6 clr!Thread::DoAppropriateWait+0x7d clr!CLREventBase::WaitEx+0xb6 clr!AwareLock::EnterEpilogHelper+0x104 clr!AwareLock::EnterEpilog+0x62 clr!JITutil_MonEnterWorker+0x132
疑问与解决需求
根据文档描述,PeekMessage不会分发消息而是直接返回,但上述堆栈显示WM_SHOWWINDOW消息被实际分发,触发了控件可见性变更逻辑,最终在执行Monitor.Enter时引发问题。我了解.NET的SynchronizationContext概念,但lock语句导致随机重入的情况非常罕见。
请解答以下问题:
PeekMessage是否总会分发WM_SHOW类消息?- 我的推测是否正确:在关闭大型窗口层级时,部分子窗口会收到隐藏/显示类消息并被分发?
- 该如何解决这个问题?有没有相关的处理指导?
内容的提问来源于stack exchange,提问作者Alois Kraus
相关产品推荐
相关产品推荐

