FrameworkWPFで例外が処理されずに最上位のベントハンドラから例外がthrowされた場合、アプリがクラッシュします。アプリがクラッシュすると、以下のような、OSのアプリのクラッシュレポートダイアログが表示され、以上が発生したことがユーザーに通知されます。この動き、なんの前触れもなくアプリが消えるよりは幾分ですが、ユーザーフレンドリーではありませんし、開発者もこの時、ほぼ何の情報も取れません。従って実質的に無意味だったりします。未処理の例外を処理する必要が出てくるのため、今回はその対処法を紹介したいと思います。WPFにMainメソッドが無い問題に対応する前提として、WPFで未処理の例外を処理する場合、じゃあその処理をどこに書けばいいのかという問題があります。見えるところでやるなら、WPFのメインウインドウクラスのコンストラクタに処理書くというのが真っ先に頭に浮かびますが、これではタイミングが遅すぎる場合があります。従って、メインウインドウのインスタンスを生成する前に実行したいです。WPFだとMain関数が見当たらないのです。これは、WPFではMain関数はコンパイル時に自動生成されためで、プログラマーは直接触れないことになっているからです。同じ意味を持つStartupイベントハンドラに処理を記述することになります。Starupイベントの作り方です。最初にApp.xamlに以下記述を追記します。<Application.Resources/></Application>で、App.xamlの実装のApp.xaml.csにイベントハンドラの中身を記述します。}}2種類の例外に対応するWPFはGUIのため、考慮しないといけない例外は基本的に2種類、WindowsFormsHostをWPF上で使用している場合3種類です。それぞれ以下の通りです。「WPFのUIスレッド上で発生した例外」の処理ですが、これはApplicationを継承したAppクラスに専用のイベントハンドラ「DispatcherUnhandledException」が用意されているので、これを使用します。先ほどのApp.xamlに以下の通り処理を追記します。<Application.Resources/></Application>VisualStudioのGUIで操作するとイベントハンドラが勝手にApp.xaml.csに追加されるので例外発生時の処理を追記します。すると例外が起きた後も画面が終了しません。}}次に、「WPFのウインドウスレッド以外で発生した例外」と「WinFormHost上のWinFormコントーロールで発生した例外」ですがこれは冒頭の、Starupメソッド内に記述します。WinFormHostは滅多に使わないと思いますが、使用方法はWinFrom時代の未処理の例外の設定方法と同じです。WPFではStartupに書くということくらいしか違いはありません。true;を記述するとDispatcherUnhandledExceptionで拾われた例外はUnhandledExceptionに拾われなくなる動作です。UnhandledExceptionの順にハンドラが2種類とも呼ばれて、終了後にアプリが落ちてしまいます。UnhandledExceptionが呼ばれると、ハンドラ終了後にアプリがクラッシュ扱いで終了してしまうのでEnvironment.Exit()で自分を安全に終了させます。リソースの解放なども必要であればここで処理を行います。ThreadExceptionで拾った例外は自動で処理済みとなるようです。UnhandledExceptionは反応しません。なんか挙動が変な時があるので少し動きを見た方がいいと思います。catchが続きます。DRYの精神に思いっきり反してますし、何かcatch説に固有の処理が無い場合、先述の例外ハンドラに任せてこのような記述は全て削除することができます。以下ずっと同じ}【おまけ】新しい例外ハンドルの方法.NET4.0以降では以下の2つの機能が追加されています。以下の処理はWPFだとかUIスレッドなどは関係なく.NET内共通で使用できる例外処理の仕組みです。それぞれい以下の通りです。例外が発生した瞬間、catch節やハンドラに入る前に例外を補足する仕組みバックグラウンドタスクで発生した例外を処理する仕組み「例外が発生した瞬間、catch節やハンドラに入る前に例外を補足する仕組み」ですが、MVVMでバインドしているプロパティとか内部で発生した例外とかも拾えるのでデバッグの時は結構有効だと思います。使用方法はAppDomainのFirstChanceExceptionにハンドラを設定します。};}第2引数の.Exceptionで発生した例外が取れます。すごい数が取れる場合があるので常に有効だとちょっとキツいかもしれません。「バックグラウンドタスクで発生した例外を処理する仕組み」ですが、こちらは、TaskScheduler.UnobservedTaskExceptionにハンドラを指定します。インスタンスがGCで破棄されるときに実行されるみたいで、反応がちょっと「遅い」です。処理済みとしてアプリを終了させないために以下メソッドを呼び出します。};}Taskを使用して終了を待たない場合、上記処理を使用して例外の発生を処理するのが良いと思います。catchで囲む記述をしないことが大切かと思います。(イベントハンドラの時と同じですね。»Profile受託ソフト会社員でWin系業務屋。趣味でCocos2d-x/C++を触っています。etc...主に受託・開発ネタ、Windowsの事、Srellaris、ゲーム制作の進捗の事を喋ります。Core3.xとUnityでAES暗号化を利用するC#の標準機能でデータを圧縮・展開するC#で属性を利用して処理に制約の説明を追加するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。