我使用Application.ThreadException事件来处理和记录我的winforms应用程序中的意外的异常。非常奇怪的Application.ThreadException行为
现在,在我的应用程序的某个地方,我有以下代码(或等价的东西相当,但这种虚拟的代码足以重现我的问题):
try
{
throw new NullReferenceException("test");
}
catch (Exception ex)
{
throw new Exception("test2", ex);
}
我清楚地期待我Application_ThreadException处理程序通过“test2”异常,但情况并非总是如此。通常,如果另一个线程将我的代码编组到UI中,我的处理程序会收到“测试”异常,就好像我没有抓到“测试”一样。
这里是一个简短的例子,再现这种行为。我省略了设计者的代码。
static class Program
{
[STAThread]
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // has no impact in this scenario, can be commented.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//this handler is never called
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Console.WriteLine(e.Exception.Message);
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Click+=new EventHandler(button1_Click);
}
protected override void OnLoad(EventArgs e) {
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThrowEx));
t.Start();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
throw new NullReferenceException("test");
}
catch (Exception ex)
{
throw new Exception("test2", ex);
}
}
void ThrowEx()
{
this.BeginInvoke(new EventHandler(button1_Click));
}
}
我的计算机上运行此程序的输出是:
test
... here I click button1
test2
我转载此.NET的2.0,3.5和4.0。有人有合理的解释吗?
更改了答案。 – 2010-06-09 15:35:01
你的建议很有道理,但这并不能改变这种奇怪的行为。 – Brann 2010-06-09 15:37:36
@Brann,你是对的。奇怪的行为依然存在。但是,我已经通过在按钮点击处理程序中不执行catch(Exception ex)来纠正它,而只是“catch”。很有意思。不会抛出Exception和Exception的异常。 – 2010-06-09 15:40:43