主窗口关闭时SynchronizationContext会发生什么?

时间:2011-12-17 23:36:11

标签: wpf f#

我正在编写一个使用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没有任何变化会导致我认为它不再有效,所以我不知道如何检查它是否可以安全切换。

1 个答案:

答案 0 :(得分:2)

(重新发表评论)

对于Application.Current.ShutdownMode的值,您看到的行为是预期的 - 因为当您的主窗口关闭时,您没有打开除主窗口以外的其他窗口(引用文档)

  当应用程序中的最后一个窗口关闭时,Windows Presentation Foundation(WPF)会隐式调用Shutdown

当然,调用Shutdown(直接或间接)显式终止该过程。

如果您希望您的流程在所有窗口关闭后仍保持活动状态,则必须将值ShutdownMode.OnExplicitShutdown分配给Application.Current.ShutdownMode

  

某些应用程序的生命周期可能不依赖于主窗口或最后一个窗口何时关闭,或者根本不依赖于窗口。对于这些方案,您需要将ShutdownMode属性设置为OnExplicitShutdown,这需要显式Shutdown方法调用来停止应用程序。否则,应用程序将继续在后台运行。

听起来像你的确切场景。 ; - ]