2011-11-25 75 views
1

我有一段时间处于挂起状态的.NET窗体窗体应用程序。当我把流程转储并通过WinDbg/SOS打开它时,它显示一个线程有一个对kernel32!WaitForMultipleObjectsEx的调用,但我没有在该特定方法的任何事件对象上调用任何WaitXXX API。在我正在对InvokedRequired和IsDisposed API进行检查时说过。是否调用InvokedRequired或IsDisposed API在内部调用任何WaitXXX API?为什么在这个方法中看到对WaitForMultipleObjectsEx的调用?

这是线程的调用堆栈。

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

为什么你不告诉我们当时你的代码在做什么? – Gabe

回答

1

Check out this postthis post他们会有所帮助,他们会告诉你所有不同的.NET线程正常通话所以才比较,并找出什么问题..

编辑:
This great post显示为什么WaitOne API在调用详细信息时调用以及为什么发生挂起。了解细节可能会帮助你避免这些挂起。

+0

感谢HaLaBi,我在这里讨论的线程是调用我的一个方法,所以我不认为这个可以被忽略。尽管我已经阅读过这个博客。 –

+1

@Palm Snow,检查编辑。 – 2011-11-25 18:09:16

+0

这篇关于WaitOne API的其他文章真的很有帮助 –

0

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

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

+0

这是什么意思它的应用程序挂在这个调用调用?还有关于如何最好地调用Control.Invoke的任何链接/建议/设计模式? –

+0

如果您有死锁 - 如果UI线程正在等待该线程完成,则会发生这种情况。使用调试器来查看调用堆栈并找出你的代码正在做什么。 – SLaks

+0

感谢您的提示。我已经看过!线程命令和所有托管线程的LockCount = 0。同样,syncBlk输出也没有。似乎不是它的僵局。因为这是我看到的调用我的代码的唯一托管线程,并处于等待状态 –

1

Win32(以及.NET)中的许多操作都会阻塞。因为在所有阻塞的API下实际上是一个带有等待的异步调用,所以当用户线程正在等待来自内核线程的某些内容时,这种等待调用是堆栈上的一项常见功能。

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

相关问题