为什么我会在此方法中看到对 WaitForMultipleObjectsEx 的调用?

问题描述 投票:0回答:3

我有一个 .NET Windows 窗体应用程序,它偶尔会处于挂起状态。当我转储进程并通过 WinDbg/SOS 打开它时,它显示一个线程调用了

kernel32!WaitForMultipleObjectsEx
,尽管我没有在该特定方法中的任何事件对象上调用任何 WaitXXX API。上面已经说过,我正在检查 InvokedRequired 和 IsDispose API。对 InvokedRequired 或 IsDispose API 的任何调用是否会在内部调用任何 WaitXXX API?

这是线程的调用堆栈。

[HelperMethodFrame_1OBJ: 0e4eedc0] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)  
0e4eee6c 67b7689f System.Threading.WaitHandle.WaitOne(Int64, Boolean)  
0e4eee88 67b76855 System.Threading.WaitHandle.WaitOne(Int32, Boolean)  
0e4eee9c 65c21a4f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)  
0e4eeeb0 65f5d68b System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)  
0e4eef50 65c233ac System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])  
0e4eef84 65c2334f System.Windows.Forms.Control.Invoke(System.Delegate)  
0e4eef88 6715ad76 MyNameSpace.MyClass.MyMethod()  
0e4eefb0 67b96e96 System.Threading.ThreadHelper.ThreadStart_Context(System.Object)  
0e4eefbc 67ba031f System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)  
0e4eefd4 67b96e14 System.Threading.ThreadHelper.ThreadStart()  
0e4ef1fc 68f81b4c [GCFrame: 0e4ef1fc]   
c# multithreading windbg sos
3个回答
1
投票

查看这篇文章并且 这篇文章他们会很有帮助,他们会向您展示对不同 .NET 线程的所有正常调用,因此只需比较并找出问题所在。

编辑:
这篇很棒的文章详细展示了调用时调用 WaitOne API 的原因以及发生挂起的原因。了解详细信息可能会帮助您避免这些挂起。


1
投票

Win32(以及 .NET)中的许多操作将被阻止。因为所有阻塞 API 的底层实际上都是带有等待的异步调用,所以当用户线程等待来自内核线程的某些内容时,此类等待调用是堆栈上的常见功能。

更新(现在我看到你的调用堆栈):等待是因为调用

Invoke
的线程需要等待UI线程完成操作才能返回。
WaitForMultipleObjectsEx
是内核句柄上任何用户模式等待的底层等待 API(在本例中可能是一个 Event 对象)。


0
投票

有很多 .Net 方法在内部执行等待。

例如,

Control.Invoke
将等待事件句柄,直到 UI 线程运行回调。

© www.soinside.com 2019 - 2024. All rights reserved.