2017-08-06 4 views
0

この質問をより詳細な最小限の完全かつ検証可能な例にするために、私は最初から始めて、最小限の方法で問題を再現しようとしています。 。私はグローバル処理できない例外ハンドラを実装しようとした新しい質問リンクUnhandledExceptionHandlerによってキャッチされない別のクラスで例外が発生しました。Visual C#(MOVED)

Problem Reproduced and Isolated Here

のために待機してください。

私はWFA(Windowsフォームアプリケーション)を持っています。 PROGRAMクラスの

、私は次のコード

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Utility.UnhandledExceptionOccurred); 
     Application.ThreadException += new ThreadExceptionEventHandler(Utility.UnhandledExceptionOccurred); 
     if (!EventLog.SourceExists("TestEventSource")) 
     { 
      EventLog.CreateEventSource("TestEventSource", "TestEventLog"); 
      MessageBox.Show("EventLog and Source Created. Restart Please"); 
      return; 
     } 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 


} 

私は、メインUIスレッドで例外が発生した場合これは、このコードはイベントハンドラ

static class Utility 
{ 
    public static void UnhandledExceptionOccurred(object sender, UnhandledExceptionEventArgs e) 
    { 
     MessageBox.Show("This Program Has Crashed\r\nPlease report this to nearest IT specialist " + 
      "and restart the program"); 
     Exception E = (Exception)e.ExceptionObject; 
     var errMsg = "UNHANDLED EXCEPTION \r\n"; 
     errMsg += "OUTER: " + E.Message + "\r\n"; 
     Exception Inner = E.InnerException; 
     int i = 1; 
     while (Inner != null) 
     { 
      errMsg += "INNER " + i.ToString() + ": " + Inner.Message + "\r\n"; 
      Inner = Inner.InnerException; 
      i++; 
     } 
     errMsg += E.StackTrace; 
     EventLog.WriteEntry("TestEventSource", errMsg, EventLogEntryType.Error); 
     Application.Exit(); 
    } 

    public static void UnhandledExceptionOccurred(object sender, ThreadExceptionEventArgs e) 
    { 
     MessageBox.Show("This Program Has Crashed\r\nPlease report this to nearest IT specialist " + 
      "and restart the program"); 
     Exception E = e.Exception; 
     var errMsg = "UNHANDLED EXCEPTION \r\n"; 
     errMsg += "OUTER: " + E.Message + "\r\n"; 
     Exception Inner = E.InnerException; 
     int i = 1; 
     while (Inner != null) 
     { 
      errMsg += "INNER " + i.ToString() + ": " + Inner.Message + "\r\n"; 
      Inner = Inner.InnerException; 
      i++; 
     } 
     errMsg += E.StackTrace; 
     EventLog.WriteEntry("TestEventSource", errMsg, EventLogEntryType.Error); 
     Application.Exit(); 
    } 
} 

とユーティリティクラスですがimpliment例外をキャッチし、システムイベントログに書き込み、終了します。

しかし、同じ名前空間に新しいクラスがあるとします。

class Foo 
{ 
    public Foo() 
    { 
     throw new Exception("A"); 
    } 

} 

次にForm1_onLoadに、私は次のコード

 public void FormLoaded(object sender, EventArgs e) 
    { 
     var F = new Foo(); 
    } 

例外が発生しませんが、決してキャッチさを実行します。

私が知る限り、バックグラウンドで実行されている2番目のスレッドはありません。これは新しいUnhandledExceptionハンドラを実装する必要があります。ある?

ここでは何が起こっていますか?私のクラスがすべて同じ名前空間にある場合、なぜこれらの未処理の例外がアプリケーション内のハンドルによって捕捉されないのでしょうか?

NO、私はFormLoadedで新しいはFoo()を作成すると同時に、()をForm1のコンストラクタで例外を上げていないです

{ 

    public EventLog Log = new EventLog(); 
    Person P; 
    public Form1() 
    { 
     InitializeComponent(); 
     Log.Source = "TestEventSource"; 
     Log.WriteEntry("Form Initialized and Running"); 
     throw new Exception("Exeption here is Caught"); 
    } 

    public void FormLoaded(object sender, EventArgs e) 
    { 
     var F = new Foo(); //Exceptions here are not caught 
    } 
} 

いくつかのより多くのソース。ただ明確にする。どちらか一方です。 Form1()コンストラクタで例外を発生させると、それが捕捉されます。 Form1()コンストラクターで例外を発生させ、Form1Loadで新しいFoo()を作成すると例外がキャッチされません。

+0

複数のクラスにはたくさんのコードがあります。私は簡単にコピー/貼り付け/コンパイル/実行できる[mcve]にこれを減らそうとしてください - 私は30行以上はないと思いますこれを実証する。 –

+0

申し訳ありません。学んだ教訓。 –

+0

@JonSkeet問題を再現して隔離することができました。 https://stackoverflow.com/questions/45534142/exception-raised-by-timer-elapsed-not-caught-by-attempted-global-exception-event –

答えて

1

ほとんどのコードをコピーし、例外処理コードをDebugger.Break()に置き換え、EventLogのものをスキップして実行しました。 OnLoadFooを作成すると、ThreadExceptionEventArgsのハンドラーが呼び出され、フォームコンストラクターでFooが作成され、UnhandledExceptionEventArgsという名前が付けられます。

私はEDIT 1小さなテストプロジェクトを作成し、あなたのコードを実行し、すべてが期待どおりに動作します(VS2015コミュニティ、AnyCpu/x64の、.NET 4.0)

:今、私はそれを得ると思います
..あなたの問題は、あなたが例外コードをForm.OnLoadで実行した場合、Visual Studioがあなたのために「ブレーク」し、処理されない例外ウィンドウが表示されるということです。...押しF5は継続すると、あなたの例外ハンドラが呼び出されなければなりません

限り、私はあなたがDebug -> Windows -> Exception settings

EDIT 2の下で、この動作を変更することができます覚えている:
それとも、これをだろうか? https://stackoverflow.com/a/1583427/8400446

+0

マイケル私は自分の問題を解決することができました。おそらくあなたは私が推測できるものを見ることに興味がありますか? https://stackoverflow.com/questions/45534142/exception-raised-by-timer-elapsed-not-caught-by-attempted-global-exception-event –

関連する問題