Gameの終了は、Dispose()を呼び出せばよいようだが、UnhandledExceptionが発生し、アプリが終了してしまう。OnNavigatedFrom()に記述したデバッグ文が呼び出されているところから、XAMLのPageに戻ってはいる様子。
ログを見ると、Gameオブジェクトがなくなったのに、Mouse周りのイベントが刈り取られず、イベントの宛先がNullであると言っている(Disposeしたから当然だが)。これが致命傷になり、アプリの継続が不可になっている。
ちなみに、Exit()を呼び出すと、GamePageに戻ることなく、アプリが終了する。
本来は、MonoGame側の対処を望みたいところだが、何とか先に進めてみる。まず、Gameの終了をGamePage側から行うため、イベントを自作し、ゲームの終了をGameからGamePageに伝える。
そこで、GamePageを起動したMainPageにGoBack()で遷移する(L.70)。UIとは別Threadに居るので、Dispatcher.RunAsync() 経由。念のため、例外発生前に遷移指示を済ませる。
その上で、GameをDispose()する(L.84)。一つ前のSuppressDraw()は例外抑止に効果なし。発生するUnhandledExceptionは、ここのtry/catchでは拾えない。
UnhandledExceptionを拾うために、App.xaml.csにハンドラを登録(L.32,33)。2つ登録しているが、MonoGameの例外を拾うのは、CoreApplication.UnhandledErrorDetectedの方。
ハンドラの実体。CoreApplication.UnhandledErrorDetectedを受けるのは、CatchCoreUnhandledException()の方(L.133)。引数のargsには、Messageがないので、Propagate()で改めてThrow(L.147)。このあたりは、
atmarkitの記事を参考に。
記事にあるように、VisualStudioのプロジェクトのPropertyで、条件付きコンパイルシンボルを設定しないと、Debugモードの実行では、アプリのハンドラの代わりにVisualStudioのデバッガが例外を捕まえるので注意。
すると、例外の実体が、NullReferenceExceptionであることがわかる。
こうして、UnhandledExceptionを受けとめると、例外でアプリが落ちることなく、GamePageから遷移したMainPageが無事に表示される。とりあえずは、これで先に進める。
セコメントをする