「C Sharpの基礎 - 例外処理」の版間の差分
ナビゲーションに移動
検索に移動
細 (Wiki がページ「適切に処理されなかった例外をキャッチする(C Sharp)」を「C Sharpの基礎 - 例外処理」に、リダイレクトを残さずに移動しました) |
編集の要約なし |
||
1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
Windowsフォームやコンソールを実装する際、例外が発生する可能性がある個所では、<br> | Windowsフォームやコンソールを実装する際、例外が発生する可能性がある個所では、<br> | ||
Try-Catch構文によりその例外をキャッチして適切な処置を施す必要がある。<br><br> | Try-Catch構文によりその例外をキャッチして適切な処置を施す必要がある。<br> | ||
<br><br> | |||
== 処理されていない例外をハンドルする == | |||
一般的に、例外が正しくキャッチ(トラップ)されていないというケースは多々ある。<br> | |||
<br> | |||
その場合、ソフトウェアの実行中において、以下のような.NET Framework標準のエラーダイアログが表示されてしまう。<br> | |||
このエラーダイアログは、ユーザにとって理解しにくい。<br> | |||
[[ファイル:Catch exception 01.gif|フレームなし|中央]] | [[ファイル:Catch exception 01.gif|フレームなし|中央]] | ||
<br> | <br> | ||
これを避けるために、.NET Framework標準のエラーダイアログを、自作のエラーダイアログに切り替えたいという要望も多い。<br> | |||
<br> | |||
ここでは、処理されていない例外を1ヶ所に纏めてハンドルする方法を記載する。<br> | |||
この方法により、ハンドルしたメソッド内で独自に作成したエラーダイアログを表示すれば、前述の要望も実現可能である。<br><br> | この方法により、ハンドルしたメソッド内で独自に作成したエラーダイアログを表示すれば、前述の要望も実現可能である。<br> | ||
<br> | |||
* Application.ThreadExceptionイベントの活用 | |||
* | *: 処理されなかった例外をハンドルするには、WindowsフォームならApplicationクラス(System.Windows.Forms名前空間)の | ||
:処理されなかった例外をハンドルするには、WindowsフォームならApplicationクラス(System.Windows.Forms名前空間)の | *: ThreadExceptionイベントをハンドルして処理する。 | ||
:ThreadExceptionイベントをハンドルして処理する。 | *: このイベントは、Windowsフォームのメインスレッド(ApplicationクラスのRunメソッドにより実行されるアプリケーションのコンテキスト)内で | ||
:このイベントは、Windowsフォームのメインスレッド(ApplicationクラスのRunメソッドにより実行されるアプリケーションのコンテキスト)内で | *: 発生した未処理の例外をハンドルするためのものである。 | ||
:発生した未処理の例外をハンドルするためのものである。 | *: <br> | ||
* Thread.GetDomain().UnhandledExceptionイベントの活用 | |||
* | *: では、上記のメイン・スレッド以外のコンテキスト上で発生した例外は、 | ||
:では、上記のメイン・スレッド以外のコンテキスト上で発生した例外は、 | *: 現在のアプリケーションドメイン(AppDomainクラス(System名前空間)のThread.GetDomainメソッドにより取得できる)の | ||
:現在のアプリケーションドメイン(AppDomainクラス(System名前空間)のThread.GetDomainメソッドにより取得できる)の | *: UnhandledExceptionイベントで出来る。 | ||
:UnhandledExceptionイベントで出来る。 | *: 例えば、マルチスレッド処理において、メインスレッド以外のスレッドで発生した例外やコンソールで発生した例外等は、 | ||
:例えば、マルチスレッド処理において、メインスレッド以外のスレッドで発生した例外やコンソールで発生した例外等は、 | *: 全てこのUnhandledExceptionイベントをハンドルして処理すればよい。 | ||
:全てこのUnhandledExceptionイベントをハンドルして処理すればよい。 | <br> | ||
以下の例では、上記2つのイベントを活用して、未処理の例外を実際に処理している。<br> | |||
<syntaxhighlight lang="c#"> | |||
< | |||
using System; | using System; | ||
using System.Windows.Forms; | using System.Windows.Forms; | ||
79行目: | 81行目: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] |
2021年3月26日 (金) 22:15時点における版
概要
Windowsフォームやコンソールを実装する際、例外が発生する可能性がある個所では、
Try-Catch構文によりその例外をキャッチして適切な処置を施す必要がある。
処理されていない例外をハンドルする
一般的に、例外が正しくキャッチ(トラップ)されていないというケースは多々ある。
その場合、ソフトウェアの実行中において、以下のような.NET Framework標準のエラーダイアログが表示されてしまう。
このエラーダイアログは、ユーザにとって理解しにくい。
これを避けるために、.NET Framework標準のエラーダイアログを、自作のエラーダイアログに切り替えたいという要望も多い。
ここでは、処理されていない例外を1ヶ所に纏めてハンドルする方法を記載する。
この方法により、ハンドルしたメソッド内で独自に作成したエラーダイアログを表示すれば、前述の要望も実現可能である。
- Application.ThreadExceptionイベントの活用
- 処理されなかった例外をハンドルするには、WindowsフォームならApplicationクラス(System.Windows.Forms名前空間)の
- ThreadExceptionイベントをハンドルして処理する。
- このイベントは、Windowsフォームのメインスレッド(ApplicationクラスのRunメソッドにより実行されるアプリケーションのコンテキスト)内で
- 発生した未処理の例外をハンドルするためのものである。
- Thread.GetDomain().UnhandledExceptionイベントの活用
- では、上記のメイン・スレッド以外のコンテキスト上で発生した例外は、
- 現在のアプリケーションドメイン(AppDomainクラス(System名前空間)のThread.GetDomainメソッドにより取得できる)の
- UnhandledExceptionイベントで出来る。
- 例えば、マルチスレッド処理において、メインスレッド以外のスレッドで発生した例外やコンソールで発生した例外等は、
- 全てこのUnhandledExceptionイベントをハンドルして処理すればよい。
以下の例では、上記2つのイベントを活用して、未処理の例外を実際に処理している。
using System;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApplication1
{
public class Program
{
[STAThread]
static void Main()
{
// ThreadExceptionイベント・ハンドラを登録する
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
// UnhandledExceptionイベント・ハンドラを登録する
Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException);
// メイン・スレッド以外の例外はUnhandledExceptionでハンドル
//string buffer = "1"; char error = buffer[2];
// ここで実行されるメインスレッドの例外はApplication_ThreadExceptionでハンドルできる
Application.Run(new Form1());
}
// 未処理例外をキャッチするイベントハンドラ
// (Windowsアプリケーション用)
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ShowErrorMessage(e.Exception, "Application_ThreadExceptionによる例外通知です。");
}
// 未処理例外をキャッチするイベントハンドラ
// (主にコンソール用)
public static void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
{
ShowErrorMessage(ex, "Application_UnhandledExceptionによる例外通知です。");
}
}
// ユーザー・フレンドリなダイアログを表示するメソッド
public static void ShowErrorMessage(Exception ex, string extraMessage)
{
MessageBox.Show(extraMessage + @" \n――――――――\n\n" + @"エラーが発生しました。開発元にお知らせください\n\n" +
@"【エラー内容】\n" + ex.Message + "\n\n" + @"【スタックトレース】\n" + ex.StackTrace);
}
}
}