この質問をより詳細な最小限の完全かつ検証可能な例にするために、私は最初から始めて、最小限の方法で問題を再現しようとしています。 。私はグローバル処理できない例外ハンドラを実装しようとした新しい質問リンク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()を作成すると例外がキャッチされません。
複数のクラスにはたくさんのコードがあります。私は簡単にコピー/貼り付け/コンパイル/実行できる[mcve]にこれを減らそうとしてください - 私は30行以上はないと思いますこれを実証する。 –
申し訳ありません。学んだ教訓。 –
@JonSkeet問題を再現して隔離することができました。 https://stackoverflow.com/questions/45534142/exception-raised-by-timer-elapsed-not-caught-by-attempted-global-exception-event –