调整包含HostVisual + D3DImage的窗口大小时WPF应用程序中的死锁

时间:2016-04-28 07:44:20

标签: wpf multithreading deadlock

我编写了一个WPF应用程序,它使用D3DImage来显示在单独的线程中生成的渲染。通过使用D3D线程中的D3DImage在UI线程中刷新Dispatcher.Invoke

D3D线程正在运行自己的调度程序。

我想使用HostVisual,所以我做了以下内容:

  • 在D3D线程中创建D3DImage并仅使用该线程
  • 从UI线程创建VisualHost添加到窗口的可视化树
  • 从D3D主题创建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中的错误还是我错过了什么?

0 个答案:

没有答案