- ベストアンサー
C#で捕捉されない例外処理の対処法とは?
- C#で作成した自前のプログラムでたまにダイアログが出力される事象を抑止したい方法について解説します。
- アプリケーションのコンポーネントで発生するハンドルされていない例外について、[続行]と[終了]の選択肢が表示されるダイアログが出現する現象に対する解決策を紹介します。
- ダイアログに表示されるオプションボタンや×ボタンを使用して、不要なダイアログを抑止する方法を具体的に説明します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
Thread.GetDomainメソッドはスレッドが実行されているアプリケーションドメインを返すメソッドですので同じ処理になります。 コンストラクタでハンドルされない例外が発生すると, 実際には ThreadException イベントは発生しませんのでメインスレッド側ではここが抜け道になってしまいます。 ThreadException イベントはメインスレッドでメッセージループが実行されたら発生するようになる のでメッセージループ前に発生しそうなものはtry-catchを入れればほとんど防げると思います。 自分でソケットを作成して通信処理している場合はパケット処理をするために作成した部分などで 思いもよらぬミスや見落としなどから例外が発生することが比較的多いので注意してソースを 見直すと間違えを見つけて例外が発生しなくなることもあります。 ハンドルされていない例外の処理 http://www.hrk-exp.net/2011/04/20110414.html ずばり!という回答ができずすみません(T_T) スレッド処理は過去同じく例外特定が困難で修正に苦労した記憶があります。。。 開発環境上でデバッグ実行などで処理させると特定できるものもありますので ミスがないか、MicrosoftがMSDN等で認めている.Net Frameworkのバグがないかを確認 をしてみてください。 再現性が悪いものは原因特定がよけい大変ですが、再現性が低い=思わぬところにミスがあり 特定条件で発生するバグの可能性が大きいので見落としがあるかもしれません。 過去Microsoft側のバグでどうやっても防げない例外が発生するものがありましたが。。。 例外補足についていろいろ調べられた方のURLも記載しておきましたのでそちらも ご参考になれば幸いです。
その他の回答 (4)
- P_DIZZY
- ベストアンサー率50% (5/10)
フォームとは別のスレッドで発生した例外を処理するということでしょうか。 先ほどの参考にされていたURLのイベントですが, Application.ThreadExceptionイベントでは 注意する点が数点あります。 ・Windows Formsアプリケーションでのみ使用が可能である ・イベントが発生するのはメインスレッドで例外が発生した場合のみである (別スレッドのようなのでここで抜けてしまっている可能性がありますね) ・ThreadExceptionイベントハンドラ内でアプリケーションを終了させるコードを記述しないとアプリケーションは終了しない ・.NET Framework 1.1 SP1でApplication.ThreadExceptionイベントが発生しないケースがある 別スレッドの場合は「AppDomain.UnhandledExceptionイベント」こちらをご使用ください。 //フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //UnhandledExceptionイベントハンドラを追加 System.AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); //次のようにもできる //System.AppDomain curDom = System.Threading.Thread.GetDomain(); //curDom.UnhandledException += // new UnhandledExceptionEventHandler( // CurrentDomain_UnhandledException); } //UnhandledExceptionイベントハンドラ private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { Exception ex = (Exception)e.ExceptionObject; //エラーメッセージを表示する MessageBox.Show(ex.Message, "エラー"); } finally { //アプリケーションを終了する Application.Exit(); } } こちらのイベントについての注意点は下記のとおりとなります。 ・ThreadExceptionイベントとは違い、Windows Forms アプリケーションだけでなく、コンソールアプリケーションでも使える ・ThreadExceptionイベントとは違い、メインスレッド以外のスレッドで例外がスローされたときも発生します。 ・.NET Framework 1.1以前では、メインスレッド以外のスレッドでスローされた例外によりThreadExceptionイベントが発生した場合は、アプリケーションが終了しない。 (UnhandledExceptionEventArgs.IsTerminatingプロパティがFalseになります)。 ・メインスレッドで例外がスローされたときは、「アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。...」というダイアログが表示され、UnhandledExceptionイベントは発生し (メインスレッドでの場合はThreadExceptionを使用してください。)
- P_DIZZY
- ベストアンサー率50% (5/10)
プログラム上のどこかでバグが存在しています。 メソッドにtry-catchを入れることで例外処理が可能です。 private void hogehoge() { try { ・・・・ } catch(Exception e) { ・・・・ } } のように入れると例外が発生した場合はcatch内の処理を実行するように なります。 Exception eにはエラーのメッセージなどが保存されていますので 表示するとどこでエラーが起きてるか分かりやすくなります。 これを入れてcatchに飛ぶ場所をブレイクポイントを入れてステップ実行 で探してバグを見つけて直すこともできます。 try-catchでも捕まえられない例外も存在しますのでその点だけはご注意下さい。 ほとんどの場合これでエラーダイアログがWindowsから通知されることはなくなります。
補足
ご回答誠に有難うございます。 言葉足らずで失礼しましたが、質問の主旨は、以下につきます。 >try-catchでも捕まえられない例外も存在しますのでその点だけはご注意下さい。 対処方法をご存じでしたら更なるご教授をよろしくお願いします。 ちなみに以下URLを参考にメインに処理されていない例外をハンドルを登録しましたが、 ログに吐かれず.NETのダイアログが出力されてしまいました。 .NET TIPS 適切に処理されなかった例外をキャッチするには? http://www.atmarkit.co.jp/fdotnet/dotnettips/320appexception/appexception.html
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
ハンドルされていない例外が発生しないようにすれば良い。 つまり、ハンドルされていない例外が発生するようなバグがあるから、バグを潰せば良い。 簡単に言えば「バグってるからバグ直してから出直して来い」って事。
- TooManyBugs
- ベストアンサー率27% (1472/5321)
バグが有るので出るのだからバグを潰せ。
お礼
P_DIZZY様 迅速に回答して頂きまして誠に有難うございました。 とても励みになりました。
補足
P_DIZZY様 迅速なご回答、誠に有難うございます。 フォーム又は複数のソケット通信のどこかで発生している例外で対象スレッドを特定できません。 try-catch-finallyの漏れもすべて確認しましたが問題なく分からないのでメインで捕捉できない 例外をすべて捉えて、その情報をログに吐き.NETのダイアログを非表示することが目標です。 再現性は低いのでテストで直ぐに原因の特定と修正による動作検証ができればよいのですが、 思うように事が運んでいない状況です。 ご教授頂いた(修正後)について質問がございます。 以下の違いにより期待結果が異なるものなのでしょうか? (修正前) //UnhandledExceptionイベントハンドラを追加 Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); (修正後) //UnhandledExceptionイベントハンドラを追加 System.AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); ググッて以下を参考にし頑張ってます。 捕捉されなかった例外がスローされたことを知る http://dobon.net/vb/dotnet/programing/unhandledexception.html AppDomain.UnhandledException イベント(.NET Framework 3.5) http://msdn.microsoft.com/ja-jp/library/system.appdomain.unhandledexception(v=VS.90).aspx Application.ThreadException イベント(.NET Framework 3.5) http://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.threadexception(v=VS.90).aspx 何卒、よろしくお願いいたします。