如果你熟悉C#或其他.NET語言,那麼一定知道異常處理。任何時候,如果你覺得有段代碼很有可能會拋出一個異常,那麼就應該用try-catch塊來處理這個異常。考慮下面的例子:
<span style="font-size:14px;">private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
s.Trim();
}</span>
很明顯,運行會出錯,因爲我試圖把Trim()方法用到一個爲null的變量上。如果你不處理這個異常,程序就會崩潰,系統不得不來處理這個問題,也就是彈出一個很不友好的界面:
用戶不得不因爲這個低級錯誤而關閉程序,然後這個錯誤是很好避免的。因此,只要你覺得哪裏可能出問題,就用try-catch,如下:
<span style="font-size:14px;">private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}</span>
然而,有時候最簡單的代碼都可能拋出異常,而我們不可能把每行代碼都用try-catch括起來。WPF允許你處理全局範圍內的異常,這是通過應用類裏面的DispatcherUnhandledException事件來實現的。只要這個事件被訂閱了,一旦異常被拋出而沒有得到處理,WPF就會觸發訂閱的方法。下面是一個完整的代碼,基於前面的例子:<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ExceptionHandlingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ExceptionHandlingSample" Height="200" Width="200">
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click">
Do something bad!
</Button>
</Grid>
</Window></span>
<span style="font-size:14px;">using System;
using System.Windows;
namespace WpfTutorialSamples.WPF_Application
{
public partial class ExceptionHandlingSample : Window
{
public ExceptionHandlingSample()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
s.Trim();
}
}
}</span>
注意我在try-catch塊外面又調用了一次Trim(),按理說,第一次的異常會被處理,第二次不會。現在我們在App.xaml裏寫下:
<span style="font-size:14px;"><Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="Application_DispatcherUnhandledException"
StartupUri="WPF Application/ExceptionHandlingSample.xaml">
<Application.Resources>
</Application.Resources>
</Application></span>
<span style="font-size:14px;">using System;
using System.Windows;
namespace WpfTutorialSamples
{
public partial class App : Application
{
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
e.Handled = true;
}
}
}</span>
處理的方法一樣,唯一的區別是提示語和圖標。同時注意到我把e.Handled設置爲true了,它告訴WPF我們已經處理了這個異常,不在需要做別的了。
總結
異常處理是程序中非常重要的一個內容,所幸WPF和.NET讓異常處理變得非常簡單,不管是本地還是全局。在重要的地方處理本地異常,全局異常僅作爲一個回調。因爲本地處理異常,允許你更細緻的解決問題。