从工作线程调用UI线程时出现死锁

leo*_*leo 11 .net c# multithreading deadlock invoke

当我从工作线程调用UI线程时,我遇到了死锁.实际上,工作线程在调用行上被阻塞:

return (ucAvancementTrtFamille)mInterfaceTraitement.Invoke(d, new object[] { psFamille });
Run Code Online (Sandbox Code Playgroud)

奇怪的是UI线程(如果我错了,纠正我,是主线程)是空闲的.

有没有办法:

  1. 看看我实际上想要调用哪个线程?
  2. 看看线程到底在做什么?

我们可以在下图中看到,Invoke行上阻塞的工作线程(ID 3732),以及MainThread在应用程序的main函数中处于空闲状态.

替代文字

编辑:这是主线程的堆栈:

替代文字

编辑2:实际上,我第二次暂停了程序,这就是堆栈的样子:

替代文字

编辑3:找到解决方法

我终于找到了解决方法.问题显然是由于异步包装器竞争条件问题.解决方法是使用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);
Run Code Online (Sandbox Code Playgroud)

它并不漂亮,但它是我找到的唯一解决方案.

Han*_*ant 5

主线程看起来并不空闲.您的屏幕截图显示它在ECM.Program.Main的当前位置.这可能是不正确的,如果它是空闲的,那么它在Application.Run()内,抽取消息循环.这是Invoke()完成所必需的.

双击主线程并切换到"调用堆栈"窗口以查看它实际执行的操作.