sti*_*ijn 2 c# wpf ironpython dispatcher sta
不久前,我们使用IronPython将Python脚本添加到Wpf应用程序中.起初,它只是"奴隶",因为例如按钮点击调用脚本然后只是运行完成将控制权返回给Wpf.后来我们添加了'master'脚本:脚本在它自己的线程中运行,并控制应用程序的其余部分.这是相当具有挑战性的,但过了一段时间,在现有的SO内容的帮助下,我们看起来很有效.从来没有真正使用它,直到现在,不幸的是事实证明它不能正常工作.核心原因是虽然有两个单独的STA线程(主要的Wpf一个和一个脚本),因此两个不同的Dispatcher实例,主线程似乎被阻止,因为脚本线程在循环中等待主线程完成(响应在脚本线程上处理的按钮单击并在主线程上启动事件).使用具有单独ui窗口的两个线程的全部意义当然不会发生.到底是怎么回事?
更新它是可重复使用最少的代码,所以我链接到它而不是在这里发布伪代码.在创建代码时,我发现当脚本线程创建的窗口未嵌入(设置MainWindow.hostedWin = false)时,不会发生死锁,并且一切都按预期运行.
回应评论所以有3个关注的线程发挥作用.我们称它们为Python,Ui和Process.Python启动Process并等待它完成.进程调用在Ui上调用.在那一点上不应该做任何事情:毕竟,它是阻塞的Python,而不是Ui,而这个结构的重点是Ui不应该与Python交互.好吧,除了它确实以某种方式.哪个是罪魁祸首.在僵局中,Ui坐在那里,PresentationFramework.dll!System.Windows.Interop.HwndHost.OnWindowPositionChanged(System.Windows.Rect rcBoundingBox) + 0x82 bytes而Process坐在WindowsBase.dll!System.Windows.Threading.DispatcherOperation.DispatcherOperationEvent.WaitOne() + 0x2f bytes那里,而Python就在Thread.Sleep.
这里发生了什么,以及如何解决它?
我会保持简短,这个答案会让你开心的几率很小.这是一个三方僵局.主线程和PythonThread之间交互中最严重的一个.这种死锁发生在Windows内核中,NtUserSetWindowPos()调用无法进行.它被阻塞,等待PythonThread上的WM_LBUTTONUP回调通知完成运行.
这个死锁是由你的WpfHwndEmbedHost黑客造成的.将另一个线程或进程拥有的顶级窗口转换为子窗口是一个appcompat功能,旨在支持Windows 3.x程序.一个尚未支持线程的Windows版本,其中一个任务嵌入另一个任务的窗口并不是问题.说得温和,WPF窗口并不像这样的窗口.否则,一个众所周知的麻烦制造者,因为在浏览器窗口中嵌入Acrobat Reader的原因非常糟糕. 没有打开WS_CHILD风格的标志应该会带来缓解,但WPF并不高兴.简单地设置hostedWin为false可以解决问题.
另一个死锁是我警告过的,主线程和ProcessThread之间的交互.Dispatcher.Invoke()是危险的,它死锁,因为主线程卡在内核中.使用Dispatcher.BeginInvoke()解决了这个问题.部分地,你仍然有主线程精神紧张5秒钟.
最严重的问题是内核锁定,它会以许多其他方式咬人.您将不得不将其保留为单独的窗口以避免它.不是好消息,我敢肯定.
| 归档时间: |
|
| 查看次数: |
1338 次 |
| 最近记录: |