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

时间:2011-11-25 17:08:55

标签: c# multithreading windbg sos

我有一个.NET窗体应用程序,偶尔会处于挂起状态。当我转移进程并通过WinDbg / SOS打开它时,它显示一个线程调用kernel32!WaitForMultipleObjectsEx,尽管我没有在该特定方法中的任何事件对象上调用任何WaitXXX API。我正在检查InvokedRequired和IsDisposed API。是否调用InvokedRequired或IsDisposed API在内部调用任何WaitXXX API?

这是线程的callstack。

[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]   

3 个答案:

答案 0 :(得分:1)

Win32(以及.NET)中的许多操作都将被阻止。因为在所有阻塞API下面实际上是一个等待的异步调用,所以当用户线程在等待来自内核线程的东西时,这样的等待调用是堆栈上的常见功能。

更新(现在我看到你的调用堆栈):等待是因为调用Invoke的线程需要等待UI线程在返回之前完成操作。 WaitForMultipleObjectsEx是内核句柄上任何用户模式等待的底层等待API(在这种情况下可能是一个Event对象)。

答案 1 :(得分:1)

Check out this postthis post他们会有所帮助,他们会告诉你所有正常的调用不同的.NET线程,所以只需比较并找出问题是什么。

修改
This great post显示了在调用详细信息时调用WaitOne API的原因以及挂起发生的原因。了解详细信息可能有助于您避免这些问题。

答案 2 :(得分:0)

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

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