プロが教える店舗&オフィスのセキュリティ対策術

C#で作成した自前のプログラムでたまにダイアログが出力される事象を抑止したいので、
ご教授の程よろしくお願いいたします。

アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。
[続行]をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。
[終了]をクリックすると、アプリケーションは直ちに終了します。

スレッドを中止しようとしました。


ダイアログには、詳細(D)・続行(C)・終了(Q)ボタンと右上角の×ボタンがあり、
×ボタンでダイアログを閉じることで、その後の動作に支障はないといった現象です。

この不要なダイアログの抑止の解決策を何卒、ご教授の程よろしくお願いいたします。

A 回答 (5件)

Thread.GetDomainメソッドはスレッドが実行されているアプリケーションドメインを返すメソッドですので同じ処理になります。



コンストラクタでハンドルされない例外が発生すると, 実際には ThreadException イベントは発生しませんのでメインスレッド側ではここが抜け道になってしまいます。
ThreadException イベントはメインスレッドでメッセージループが実行されたら発生するようになる
のでメッセージループ前に発生しそうなものはtry-catchを入れればほとんど防げると思います。

自分でソケットを作成して通信処理している場合はパケット処理をするために作成した部分などで
思いもよらぬミスや見落としなどから例外が発生することが比較的多いので注意してソースを
見直すと間違えを見つけて例外が発生しなくなることもあります。

ハンドルされていない例外の処理
http://www.hrk-exp.net/2011/04/20110414.html

ずばり!という回答ができずすみません(T_T)

スレッド処理は過去同じく例外特定が困難で修正に苦労した記憶があります。。。
開発環境上でデバッグ実行などで処理させると特定できるものもありますので
ミスがないか、MicrosoftがMSDN等で認めている.Net Frameworkのバグがないかを確認
をしてみてください。
再現性が悪いものは原因特定がよけい大変ですが、再現性が低い=思わぬところにミスがあり
特定条件で発生するバグの可能性が大きいので見落としがあるかもしれません。

過去Microsoft側のバグでどうやっても防げない例外が発生するものがありましたが。。。

例外補足についていろいろ調べられた方のURLも記載しておきましたのでそちらも
ご参考になれば幸いです。
    • good
    • 0

フォームとは別のスレッドで発生した例外を処理するということでしょうか。



先ほどの参考にされていた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様 迅速なご回答、誠に有難うございます。

フォーム又は複数のソケット通信のどこかで発生している例外で対象スレッドを特定できません。
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/unhandlede …

 AppDomain.UnhandledException イベント(.NET Framework 3.5)
 http://msdn.microsoft.com/ja-jp/library/system.a …

 Application.ThreadException イベント(.NET Framework 3.5)
 http://msdn.microsoft.com/ja-jp/library/system.w …

何卒、よろしくお願いいたします。

補足日時:2012/01/11 17:44
    • good
    • 1
この回答へのお礼

P_DIZZY様 迅速に回答して頂きまして誠に有難うございました。
とても励みになりました。

お礼日時:2012/01/11 17:49

プログラム上のどこかでバグが存在しています。


メソッドに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/320 …

補足日時:2012/01/11 15:32
    • good
    • 0

ハンドルされていない例外が発生しないようにすれば良い。



つまり、ハンドルされていない例外が発生するようなバグがあるから、バグを潰せば良い。

簡単に言えば「バグってるからバグ直してから出直して来い」って事。
    • good
    • 0

バグが有るので出るのだからバグを潰せ。

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!