2009-08-19 10 views
6

これはprevious questionに関連しています。AppDomainの例外は常にアプリケーションを終了させますか?

ここで私が理解しようとしているのは、UI以外の例外が発生しない限り、UIスレッドの例外がアプリケーションを終了させることを防ぐ方法です。

参考のため、this exampleを参照してください。

最も重要なのは、エラー報告を送信するかどうかを尋ねるWindowsのダイアログボックスを表示せずに、プロセスを「サイレントに」終了することです。これは私のAppDomain UnhandledExceptionHandlerある

は:this answerのコメントに照らして

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
{    
    try 
    { 
     // Maybe do some logging here if allowed 
    } 
    catch 
    { 
    } 

    // then just terminate the application 
    Application.Exit();    
} 

UPDATE
、私が最も重要な、私はそのメカニズムの詳細についてはしたいことを明確にしたいと思いますApplication.ThreadExceptionメカニズムを使用して、未処理の例外をキャッチする機会をUIスレッドに与えることができます。そして、そのような振る舞いが非UIスレッドで実装できるかどうか。

答えて

7

だから、Googleでいくつかのより多くの検索を実行した後、私はJeff Atwood on his blogで説明したのと同じ問題に与えられたこの非常に興味深い説明を見つけました。

こんにちはすべて、 ご迷惑をおかけして申し訳ありません。この動作は実際にはデザインですが、デザインは時折複雑になることがあります。

最初に理解しなければならないのは、UnhandledExceptionイベントが未処理の例外ハンドラではないということです。 イベントに登録すると、ドキュメントに記載されているものとは逆に:-(ハンドルされていない例外は処理されません(それ以降は未処理ではありませんが、すでに循環推論で停止します) UnhandledExceptionイベントは単にケースで、あなたのスレッドまたはアプリケーションが死ぬ前の状態を保存しようとする場合、例外は未処理になったことを通知します。FWIW、私はドキュメントが固定取得するバグを提出した。

だけにv1.0と1では複雑なものになります。1の場合、処理されない例外は、アプリケーションが死ぬことを必ずしも意味しませんでした。未処理の例外がメインスレッド以外で発生した場合や、アンマネージコードで寿命を開始したスレッド以外の場合は、CLRは例外を処理し、アプリケーションの継続を許可しました。これは一般的には悪いことでした。なぜなら、たとえば、あなたのアプリケーションが実際に何の仕事もしていないまで、ThreadPoolスレッドが静かに消えていくからです。このような失敗の原因を突き止めることは、ほとんど不可能でした。これはJeffがそれが以前に働くと思った理由かもしれません...彼はちょうど非メインスレッドでクラッシュを見ただけです。

v2.0では、すべてのスレッドで未処理の例外が発生するとアプリケーションが停止します。クラッシュをデバッグするのは、前述のハングやサイレント・ストップ・オブ・ワークの問題をデバッグするよりも、はるかに簡単です。

ところで、私の1.1マシンでは、MSDNの例に期待される出力があります。デバッガを接続した後でなければ2行目が表示されません。 v2では、デバッガが接続される前にUnhandledExceptionイベントが発生するように、ほとんどの人が期待しているように、物事を逆転させました。

2005年2月18日のジョナサンKeljo CLR例外PM ジョナサンKeljo 10時02分PM

は、しかし、私はまだUIスレッドがあなたがキャッチを持ってできるようにするのトリックを達成する方法に興味がある

- すべてのUIスレッド例外のハンドラです。

さらに、私は自分のアプリケーションのみdisabling it for the whole machine as seen hereなし)

3

AppDomainの例外がアプリケーションを終了するわけではありません.AppDomainを破棄してアプリケーションを終了させるのは未処理の例外です。

ここで問題となるのは、UIスレッド例外をかなり高いレベルで明示的に処理できることです。ただし、バックグラウンドスレッドで未処理の例外が発生した場合、同じレベルで簡単に処理する手段がないため、アプリケーションに伝播してプルダウンする傾向があります。 Application.ThreadExceptionは、少なくともこれがエラーを引き起こした原因であることを知ることができ、必然的にログに記録します。

UIスレッドで未処理の例外が発生すると同じことが発生します。

+0

@Reedのための.NET JITデバッグダイアログを無効にする方法に非常に興味がある:「UIスレッドで未処理の例外が同じが発生します起こること。 " - 本当じゃない。テストアプリケーションを作成し、自分で試してみてください。 –

+1

技術的には、「メインスレッドで未処理の例外」と言わなければなりません。 Windowsフォームは、メインスレッドの動作を変更する独自の例外処理ビヘイビアをUIスレッドに追加します(UIスレッドでは完全に実行されているため)。コンソールアプリケーションを作成して試してみると、どのスレッドが発生しても問題はないことがわかります。それらはすべてアプリケーションを解体します。 –

+0

それから私は私の質問を再掲する必要があります:どのようにUIスレッドは一般的な例外処理の動作を達成するのですか?それは私が非UIスレッドの振る舞いとして再現できるものですか? –

2

これはまったく役に立ちますか?

Improved Unhandled Exception behavior in .NET 2.0

また、このコードは、 "静かに死ぬ" ようです。あなたは何か他のものを探していますか?

using System; 

namespace UnhandledException 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; 

      throw new NotImplementedException(); 
     } 

     static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      Exception exception = (Exception)e.ExceptionObject; 
      System.Console.WriteLine("exception=[" + exception.ToString() + "]"); 

      Environment.Exit(-1); 
     } 
    } 
} 
+0

はい、そうです。私はちょうどあなたがそれを投稿したときに投稿を読んでコメントを終えました。しかし、+1。.. –

+0

はい、Environemnt.Exitはトリックを行うようです! UIスレッドがキャッチオール例外をどのように達成するかについて誰かが洞察を与えることができるかどうかを確認するために、質問を少しだけ開いたままにしておきます。さもなければ、あなたは受け入れられた答えのために私の投票をするでしょう! –

+0

Application.ThreadExceptionは、「未処理例外ハンドラ」の別の変形です。多くの亜種があります(Console App vs. WinForms vs. WebForms vs. WCFなど)。私はあなたの質問を理解するか分からない。一般に、私は適用可能なものをすべて実装します。 –

関連する問題