WPF教程(十三)WPF異常處理

如果你熟悉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的變量上。如果你不處理這個異常,程序就會崩潰,系統不得不來處理這個問題,也就是彈出一個很不友好的界面:

An unhandled exception, left for Windows to deal with
用戶不得不因爲這個低級錯誤而關閉程序,然後這個錯誤是很好避免的。因此,只要你覺得哪裏可能出問題,就用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>

A locally handled exception


A globally handled exception


處理的方法一樣,唯一的區別是提示語和圖標。同時注意到我把e.Handled設置爲true了,它告訴WPF我們已經處理了這個異常,不在需要做別的了。

總結

異常處理是程序中非常重要的一個內容,所幸WPF和.NET讓異常處理變得非常簡單,不管是本地還是全局。在重要的地方處理本地異常,全局異常僅作爲一個回調。因爲本地處理異常,允許你更細緻的解決問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章