我编写了一个WPF应用程序,它使用D3DImage
来显示在单独的线程中生成的渲染。通过使用D3D线程中的D3DImage
在UI线程中刷新Dispatcher.Invoke
。
D3D线程正在运行自己的调度程序。
我想使用HostVisual
,所以我做了以下内容:
D3DImage
并仅使用该线程VisualHost
添加到窗口的可视化树VisualTarget
并将其链接到VisualHost
。这非常有效:D3DImage
的内容在主窗口中正确呈现,而不会对UI调度程序造成任何干扰......
...直到我尝试调整主窗口的大小,并且应用死锁。
UI调度程序和D3D调度程序之间发生死锁。当主窗口调整大小时,我从PresentationCore / PresentationFramework的参考资源中理解的是,为新窗口大小创建了一个新的MIL通道,并且整个可视化树都会收到通知。这是UI线程上的callstack的顶部:
Dispatcher.LegacyInvokeImpl <-- locked here
HostVisual.EnsureHostedVisualConnected
HostVisual.RenderContent
UI线程正在等待D3D线程从HostVisual
完成作业。在D3D线程的一侧,调度程序执行作业并锁定在以下callstack上:
wpfgfx_v0400.dll!MilCompositionEngine_EnterCompositionEngineLock <-- locked here
HostVisual.DoHandleDuplication
问题在于,由于调整大小操作,UI线程当前获取了合成引擎的锁定,因此D3D线程永远无法获取它。
这是HostVisual
/ VisualTarget
中的错误还是我错过了什么?