为了使这个问题成为一个更小,完整,可验证的例子,我从头开始尝试以最小的方式重现问题。请等待新的问题链接
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()时,不会捕获异常。
答案 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