看到題目可能有些同學覺得這是一個老生常談的問題了,確實這是一個 known issue 但我發現還是有同學在詢問這個問題,所以在這裡給大家總結分享一下。
首先第一個問題 MessageBox顯示出來以後,如果使用者不理會 Message 頁面,大概等上10秒鐘程式就會自動結束。(這個現象在Debug時不會出現)
先簡單分析一下這個問題的原因,首先為什麼在Debug的時候應用不會出問題,很簡單我們在調試應用的時候很有可能一個斷點停留10秒鐘以上(一個傳回值阻塞主線程),然而應用在非Debug的情況下出現這種現象,SDK會認為你的代碼有問題會強制退出。
其實解決這個問題的方法很簡單,既然知道這個問題的原因了,使用一個非同步方法呼叫(線程)來實解決這個問題。
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { e.Cancel = true; base.OnBackKeyPress(e); this.Dispatcher.BeginInvoke(delegate { if (MessageBox.Show("是否要退出程式?", "退出", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { } }); }
當然肯定有同學會問 在調用MessageBox之前先把 e.Cancel 設定成 True 了那怎麼退出應用呢? 這也算是一個老問題了(WP7時代遺留問題),這裡我也是總結一下經驗,從網上看到的一些方法。
Windows Phone 8 更新 此方法可以直接終結應用。
Application.Current.Terminate();
但是此方法這裡不會調用頁面的 OnNavigatedFrom 事件 和App中的Application_Closing 事件,所以在調用此方法前要注意儲存使用者資料。
Windows Phone 7
首先 XNA中的Game.Exit() 不建議使用因為在市集審核的時候會遇到問題,導致不能上商店。
目前唯一的靠譜方法就是通過拋異常並且在App檔案中的Application_UnhandledException事件中處理它:
網路上拋出異常的方式有兩種
1. 自訂的異常
private class QuitException : Exception { } public static void Quit() { throw new QuitException(); } // Code to execute on Unhandled Exceptions private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) { if (e.ExceptionObject is QuitException) return; if (System.Diagnostics.Debugger.IsAttached) { // An unhandled exception has occurred; break into the debugger System.Diagnostics.Debugger.Break(); } }
最後使用App.Quit()退出應用。
2. 利用 NavigationService.GoBack();退出應用
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { e.Cancel = true; base.OnBackKeyPress(e); this.Dispatcher.BeginInvoke(delegate { if (MessageBox.Show("是否要退出程式?", "退出", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { while (NavigationService.BackStack.Any()) { NavigationService.RemoveBackEntry(); } NavigationService.GoBack(); } }); }
同理,在 Application_UnhandledException 中處理一下這個異常。