【发布时间】:2010-09-21 16:48:18
【问题描述】:
当我从工作线程调用 UI 线程时出现死锁。事实上,工作线程在调用行被阻塞:
return (ucAvancementTrtFamille)mInterfaceTraitement.Invoke(d, new object[] { psFamille });
奇怪的是 UI 线程(如果我错了,请纠正我,它是主线程)是空闲的。
有什么办法:
- 看看我实际上试图调用哪个线程?
- 看看所说的线程到底在做什么?
我们可以在下图中看到,工作线程(ID 3732)阻塞在 Invoke 行,而 MainThread 在应用程序的 main 函数中处于空闲状态。
编辑:这里是主线程的堆栈:
Edit2:实际上,我再次暂停了程序,堆栈如下所示:
Edit3:找到解决方法
我终于找到了解决方法。问题显然是由于异步包装竞争 条件问题。解决方法是使用 BeginInvoke 并等待它超时。当它超时时,再次调用它并循环直到它最终返回。大多数情况下,它实际上在第二次调用时起作用。
IAsyncResult ar = mInterfaceTraitement.BeginInvoke(d, new object[] { psFamille });
while (!ar.AsyncWaitHandle.WaitOne(3000, false))
{
ar = mInterfaceTraitement.BeginInvoke(d, new object[] { psFamille });
}
// Async call has returned - get response
ucAvancementTrtFamille mucAvancementTrtFamille = (ucAvancementTrtFamille)mInterfaceTraitement.EndInvoke(ar);
它并不漂亮,但这是我找到的唯一解决方案。
【问题讨论】:
-
你能发布
d代表在做什么吗? -
这是一个 WinForms 或 WPF 应用程序,对吧?
-
委托只是创建了一个图形控件(此时它甚至没有将它添加到任何表单中)。我使用 WinForms。
-
UI线程是否有可能随时等待工作线程?
标签: c# .net multithreading deadlock invoke