You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:55:24