ミスのないコードを書くことは大変難しいです。
どんなに優れた人間であっても、間違いは犯します。
アプリケーションコードに致命的なバグがあるとき、アプリケーションが強制終了したりします。
ユーザーは「問題があった、直せ」この一言を口にします。
直す側は、どこをどう直せば良いのかわかりません。そんなとき
どういうときに不具合が発生するか、伝えてくださいとお願いすることになるでしょう。
最初から、再現方法と、どこでエラーが発生してくれたのかを教えてもらえるとこの問題は解決します。
システムとしてこの機構を入れることは可能なのでしょうか?
そんな疑問に答える話にしたいと思います。
バグの原因を調べる作業に時間制限があるとツライです。
まず最初に、どうにもならない例外を知っておく必要があります。
StackOverflowException
OutOfMemoryException
ThreadAbortException
この三つです。
StackOverflowExceptionは、再帰処理の終了判定がうまくいかず無限に関数を呼び出してしまった時に起きます。
起こしてみますか?
スタックオーバーフローを起こすコード
ハイライトした行をコメントアウトしてしまったため、RecursiveFunction を無限に呼び出すことになってしまいました。
関数の呼び出し履歴をのぞいてみましょう。
しまいにはスタックが満杯になり…
ま、当然ですよね。
この状態からはもはや復帰は不可能となります。
どうにもならない例外です。
OutOfMemoryException は、環境のメモリ不足によって引き起こされます。
4GB のクラスインスタンスを作成するようなコードを書いてみると起こせます。
こんな感じ↓
例の箇所を通ると…
当然のようにアプリケーションは強制終了します。
これもどうにもなりません。
ThreadAbortException は、コードから Thread.Abort を呼ばない限り起きない例外です。
スレッドを扱わない限りは出てこないので、ここでの説明は省きます。
どうすれば例外を処理できるのか
ここまで見てきた例外はどうにもならないものですが、言い換えると、それ以外はどうにかなる例外です。
C# で例外処理を行うには try/catch/finaly キーワードを使うと勉強しました。(ちょっと前に本を読んで…)
この catch に漏れがある場合に、例外から先に進めなくなり、アプリケーションが失敗します。
よく見かけるのは 0 除算でしょうか?
わざと 0 で割ってみましょう。
アプリケーションを実行中に 0 除算が発生すると、これまた何も言わずにアプリが強制終了してしまいました。
これは良くないですね。
例外ハンドルの漏れをキャッチするには次のように対処する必要があります。
ハイライトした行に注目してください。
イベントハンドラでは次のように対処します。
ハイライトした行で Handled フラグを立てていますが、これを行わないと結局例外がハンドルされなかったとみなされ
アプリケーションが強制終了してしまいます。忘れないようにしておきましょう。
先ほどと同じように 0 除算を行ってみました。
結果、次のように Exception の内容がメッセージボックスで表示されるようになりました。
「OK」を押すと、何事もなかったように処理を続けることができます。
一般的なやり方だと、キャッチされていない例外を見つけたら、エラーログを開発者へ送信するとか?
とにかく、これでどんな例外にも対処できるようになりました。
2012/04/22 初記。