I’m writing a game that uses WPF for its interface, and Direct3D11 for rendering the world. The rendering happens on its own thread but it needs to make use of a D3DImage in the window, so I need to use a SynchronizationContext to switch to the UI thread when rendering. When the game first starts up I make a DispatcherSynchronizationContext from the Application.Current.Dispatcher. Some time after this happens, a window is created and then is stored in Application.Current.MainWindow. When its time to render I have to switch to the context like so:
async {
...
do! Async.SwitchToContext state.Context
//render stuff
}
Everything is fine up until the main window closes. Once that happens my handler for Application.Exit runs, which tells all subsystems to shut down and then waits for their responses. The problem is the render thread hangs either on the next Async.SwitchToContext, or if the switch already happened just before the window closed then it hangs sometime during the actual rendering, so it can never respond to the shutdown request.
The DispatcherSynchronizationContext doesn’t become null, and both the value of DSC’s HasShutdownStarted and HasShutdownFinished are false. I’m not getting any exception either. The application is still running, it won’t exit until it gets a response from all the subsystems.
What is happening at this point in the program? The application is still running, so its dispatcher should still be there, so I should still be able to switch to its context. There is no change in the SynchronizationContext before and after the window closes that would lead me to believe its no longer valid, so I have no idea how to check if its safe to switch or not.
(Reposting from comments)
For your value of
Application.Current.ShutdownMode, the behavior you’re seeing is expected — because you have no other window open other than your main window, when your main window is closed, (quoting the docs)And of course, invoking
Shutdown(directly or indirectly) explicitly terminates the process.If you want your process to remain alive even after all windows are closed, you must assign the value
ShutdownMode.OnExplicitShutdowntoApplication.Current.ShutdownMode:Sounds like your exact scenario to me. ;-]