在未被UnhandledExceptionHandler Visual C#(MOVED)

时间:2017-08-06 06:31:39

标签: c# winforms

为了使这个问题成为一个更小,完整,可验证的例子,我从头开始尝试以最小的方式重现问题。请等待新的问题链接

Problem Reproduced and Isolated Here

我试图实现一个全局的无法处理的异常处理程序。

我有一个WFA(Windows Form App)。

在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());
    }


}

这是带有事件处理程序的Utility类

    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();
    }
}

当我在主UI线程中引发异常时,此代码可以正常工作,捕获异常,写入系统事件日志并退出。

但是,请说我在同一名称空间中有一个新类。

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

}

然后在Form1_onLoad中执行以下代码

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

异常被提出,但从未被抓住。

据我所知,后台没有运行第二个线程,我必须为它实现新的UnhandledException处理程序。有吗?

这里发生了什么?如果我的类都在同一名称空间中,为什么这些未处理的异常会被Application中的句柄捕获?

更多来源

    {

    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
    }
}

不,在FormLoaded中创建新的Foo()的同时,我没有在Form1()的构造函数中引发异常。只是为了澄清。它是一个或另一个。当我在Form1()构造函数中引发Exception时,它被捕获。当我没有在Form1()构造函数中引发异常,并在Form1Load中创建一个新的Foo()时,不会捕获异常。

1 个答案:

答案 0 :(得分:1)

我复制了大部分代码,仅使用Debugger.Break()替换了您的异常处理代码,并跳过EventLog内容并运行它。在Foo中创建OnLoad会使用ThreadExceptionEventArgs调用处理程序,在表单构造函数中创建Foo会调用UnhandledExceptionEventArgs的那个。

我创建了一个小型测试项目并运行您的代码,一切都按预期工作(VS2015社区,AnyCpu / x64,.NET 4.0)

编辑1:
现在我想我明白了......你的问题是,如果你在Form.OnLoad中运行你的异常代码,Visual Studio'为你打破'并向你显示未处理的异常窗口......那很好。按F5继续,应调用异常处理程序...

据我记得,您可以在Debug -> Windows -> Exception settings

下更改此行为

编辑2:
或者这可能是这个吗? https://stackoverflow.com/a/1583427/8400446