【发布时间】:2011-12-18 23:16:12
【问题描述】:
我正在编写一个游戏,它的界面使用 WPF,并使用 Direct3D11 渲染世界。渲染发生在它自己的线程上,但它需要在窗口中使用 D3DImage,所以我需要在渲染时使用 SynchronizationContext 切换到 UI 线程。当游戏第一次启动时,我从 Application.Current.Dispatcher 创建了一个 DispatcherSynchronizationContext。发生这种情况一段时间后,会创建一个窗口,然后将其存储在 Application.Current.MainWindow 中。当需要渲染时,我必须像这样切换到上下文:
async {
...
do! Async.SwitchToContext state.Context
//render stuff
}
在主窗口关闭之前一切都很好。一旦发生这种情况,我的 Application.Exit 处理程序就会运行,它会告诉所有子系统关闭,然后等待它们的响应。问题是渲染线程在下一个 Async.SwitchToContext 上挂起,或者如果切换已经在窗口关闭之前发生,那么它会在实际渲染期间的某个时间挂起,因此它永远无法响应关闭请求。
DispatcherSynchronizationContext 不会变为 null,并且 DSC 的 HasShutdownStarted 和 HasShutdownFinished 的值都是 false。我也没有任何例外。应用程序仍在运行,它不会退出,直到它得到所有子系统的响应。
程序中此时发生了什么?应用程序仍在运行,所以它的调度程序应该仍然存在,所以我应该仍然能够切换到它的上下文。在窗口关闭之前和之后 SynchronizationContext 没有任何变化,这会让我相信它不再有效,所以我不知道如何检查它是否可以安全切换。
【问题讨论】:
-
Application.Current.ShutdownMode的值是多少?如果是ShutdownMode.OnMainWindowClose,那么您看到的行为是预期的。 -
是否打开了另一个窗口?你有没有试过把它改成
ShutdownMode.OnExplicitShutdown? -
没有其他窗口。我刚刚尝试了 OnExplicitShutdown,它解决了这个问题。你能帮我理解其中的区别吗?在这两种情况下,调度程序在我尝试使用它时都没有关闭。