2013年10月20日

WPFサンプル:UIスレッド以外で発生した未処理例外には対応する

   このエントリーをはてなブックマークに追加 Clip to Evernote
WPFサンプル:未処理例外に対応する」 では、UIスレッド内で発生した未処理例外に対応するサンプルを掲載しましたが、UIスレッド以外で発生した未処理例外には対応できません。
UIスレッド以外で発生した未処理例外には対応するには、AppDomain.CurrentDomain.UnhandledException イベントを利用します。
そのサンプルを以下に示します。

UnhandledExceptionSample1

UnhandledExceptionSample2


UnhandledExceptionイベントハンドラの設定は、以下のように、App.xaml.csでやるのが適当かと思います。

using System;
using System.Windows;
namespace UnhandledExceptionSample {
    public partial class App : Application {
        private void Application_Startup(object sender, StartupEventArgs e) {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }
        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            Exception ex = e.ExceptionObject as Exception;
            MessageBox.Show(ex.Message, "例外発生(UI スレッド外)",
                                  MessageBoxButton.OK, MessageBoxImage.Error);
            this.Shutdown();
        }
        private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
            MessageBox.Show(e.Exception.Message, "例外発生",
                                  MessageBoxButton.OK, MessageBoxImage.Error);
            e.Handled = true;
        }
    }
}


コードを見ていただければわかると思いますが、UIっスレッド以外で発生した未処理例外の場合は、 Shutdownメソッドを呼び出して、アプリケーションを終了させています。
Shutdownメソッドの行をコメントにしても、アプリケーションは終了してしまいます。
もし、アプリケーションを終了させたくない場合は、スレッド内で発生した例外はそのスレッド内で try-catchを使い、例外処理を記述する必要があります。
App.xamlは、「WPFサンプル:未処理例外に対応する」のものと変更ありません。

<Application x:Class="UnhandledExceptionSample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"
             Startup="Application_Startup"
             DispatcherUnhandledException="Application_DispatcherUnhandledException"
             >
    <Application.Resources>
        
    </Application.Resources>
</Application>

以下、MainWindow.xaml と MainWindow.xaml.cs です。

<Window x:Class="UnhandledExceptionSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="120" Width="260" >
    <StackPanel >
        <Button Content="UIスレッドで例外発生"  Margin ="3"
                Width="186" Click="Button_Click1"/>
        <Button Content="UIスレッド外で例外発生"  Margin="3"
                Width="186" Click="Button_Click2" />
    </StackPanel>
</Window>


using System.Threading;
using System.Windows;
namespace UnhandledExceptionSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Button_Click1(object sender, RoutedEventArgs e) {
            throw new System.NotImplementedException();
        }
        private void Button_Click2(object sender, RoutedEventArgs e) {
            Thread th = new Thread(DoWork);
            th.Start();
        }
        private void DoWork(object obj) {
            throw new System.NotImplementedException();
        }
    }
}



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52342719