WPF整理-处理没有注意到的异常
在.NET中,我們使用try-catch-finally來處理異常。但,當(dāng)一個Exception拋出,拋出Exception的代碼又沒有被try包圍時,程序就崩潰了。
這些異常往往是你沒有注意到的。在WPF中,提供了一種處理這些個異常的方式。
舉例來說明。
1.先拋出個異常,不用try包圍它。
在MainWindow上添加一個如下的Button。
<Window x:Class="HandlingAnUnhandledException.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><StackPanel><Button Click="OnClick"><Button.Template><ControlTemplate><Grid><Ellipse Height="100" Width="250" Fill="Pink"/><TextBlock Text="Button to Throw Exception by DebugLZQ" VerticalAlignment="Center" HorizontalAlignment="Center"/></Grid></ControlTemplate></Button.Template></Button></StackPanel> </Window>在Button的Click事件中拋出個異常
private void OnClick(object sender, RoutedEventArgs e){throw new InvalidOperationException("Something has gone wrong.");}如果,我們Ctrl+F5運行這個程序,點擊按鈕,程序就崩潰了。
WPF如何解決這個問題呢?
2.WPF處理這種異常的方法
在App.xaml.cs中訂閱DispatcherUnhandledException事件,并添加相應(yīng)的事件處理。
App.xaml.cs如下:
public partial class App : Application{public App(){DispatcherUnhandledException += App_DispatcherUnhandledException;}void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e){ MessageBox.Show("Error encountered! Please contact support."+ Environment.NewLine + e.Exception.Message);//Shutdown(1);e.Handled = true;}}這時,當(dāng)我們Ctrl+F5運行程序。
?這樣,異常就被捕獲并處理了,程序沒有崩潰。?
?
?Update:剛百度了一下:WinForm也有類似的機制,請參考Kevin Gao的這篇博文:C# winform 捕獲全局異常.
?Update:
所有 WPF 應(yīng)用程序啟動時都會加載兩個重要的線程:一個用于呈現(xiàn)用戶界面,另一個用于管理用戶界面。呈現(xiàn)線程是一個在后臺運行的隱藏線程,因此我們通常面對的唯一線程就是 UI 線程。
這種方法只能捕捉UI線程的異常,及使用了Dispatcher進行線程關(guān)聯(lián)了的線程(其實Dispatcher.Invoke/BeginInvoke就是將要執(zhí)行的代碼,扔到UI線程去執(zhí)行)的異常。不能捕捉普通的子線程異常。
如:?
private void OnClick(object sender, RoutedEventArgs e) {Dispatcher.BeginInvoke(new Action(() => { throw new InvalidOperationException("Something has gone wrong."); })); }也可以正常捕獲。
而:
private void OnClick(object sender, RoutedEventArgs e) {Thread t = new Thread(() => { throw new InvalidOperationException("Something has gone wrong."); });t.IsBackground = true;t.Start(); }則不能捕獲。?
感謝veboys博友的指點~
------------------------------------------
同樣的,即使我們用一個try-catch包圍如下的異常,異常也不會被Handle:
try {var thread = new Thread(() => {throw new Exception(); });thread.Start(); } catch (Exception) {MessageBox.Show("Will not execute!");throw; }?
try {Task.Run(() =>{throw new Exception(); }); } catch (Exception) {MessageBox.Show("Will not execute!"); }?
--------------
對應(yīng)Async await 異常:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e){try{await Task.Run(() => { throw new Exception(); });}catch (Exception){MessageBox.Show("Will execute!");}}處理Unhandled exception異常 如下:TaskScheduler.UnobservedTaskException
public partial class App : Application{protected override void OnStartup(StartupEventArgs e){RegisterEvents();base.OnStartup(e);}private void RegisterEvents(){TaskScheduler.UnobservedTaskException += (sender, args) =>{MessageBox.Show(args.Exception.Message);args.SetObserved();};AppDomain.CurrentDomain.UnhandledException += (sender, args) => MessageBox.Show("Unhandled exception.");}}?
?Update:
WPF程序的異常捕獲總結(jié)
轉(zhuǎn)載于:https://www.cnblogs.com/DebugLZQ/p/3161185.html
總結(jié)
以上是生活随笔為你收集整理的WPF整理-处理没有注意到的异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字符与字节
- 下一篇: WPF-21:WPF实现仿安卓的图案密码