我使用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