2013-06-04 62 views
1

我的WinForms應用程序安裝Application.ThreadException事件處理程序來處理所有未處理的異常(處理程序顯示一個對話框:發生錯誤,單擊此處發送錯誤報告等)。Application.ThreadException不被調用

問題是,當應用程序顯示模態對話框時,我的事件處理程序不會被調用。當我顯示一個MessageBox或我的異常對話框時,所有異常都會被無聲地吞下。有沒有辦法抓住他們?

下面是一個模擬此行爲的示例WinForms應用程序。當這個應用程序顯示一個消息框,在後臺拋出的所有異常丟失(ThreadException處理程序不叫):

using System; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

class Program 
{ 
    static void Main() 
    { 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    var form = new MyForm(); 
    Application.ThreadException += (s, e) => 
    { 
     form.AppendText("ThreadException event handler is called."); 
     MessageBox.Show("Error: " + e.Exception); 
    }; 

    Application.EnableVisualStyles(); 
    Application.Run(form); 
    } 
} 

class MyForm : Form 
{ 
    public MyForm() 
    { 
    Controls.Add(TextBox = new TextBox 
    { 
     Multiline = true, 
     Dock = DockStyle.Fill 
    }); 

    ThrowUnhandledException(1); 
    ThrowUnhandledException(2); 
    ThrowUnhandledException(3); 
    } 

    private async void ThrowUnhandledException(int delaySeconds) 
    { 
    await Task.Delay(TimeSpan.FromSeconds(delaySeconds)); 
    AppendText("Throwing a NotImplementedException!"); 
    throw new NotImplementedException(); 
    } 

    private TextBox TextBox { get; set; } 

    public void AppendText(string message) 
    { 
    TextBox.AppendText(message + Environment.NewLine); 
    } 
} 

編輯。我更新了代碼以使事情更清晰。

當引發異常時,MyForm寫入文本框:拋出NotImplementedException!

當調用ThreadException處理程序時,它會寫入:調用ThreadException事件處理函數。,然後顯示一個消息框。

如果所有異常被抓,我的文本框會顯示以下信息:

Throwing a NotImplementedException! 
ThreadException event handler is called. 
Throwing a NotImplementedException! 
ThreadException event handler is called. 
Throwing a NotImplementedException! 
ThreadException event handler is called.

但它顯示:

Throwing a NotImplementedException! 
ThreadException event handler is called. 
Throwing a NotImplementedException! 
Throwing a NotImplementedException!

回答

2

你可以嘗試用

Application.ThreadException += (s, e) => Console.WriteLine(e.Exception); 

更換

Application.ThreadException += (s, e) => MessageBox.Show("Error: " + e.Exception); 

,你會看到該事件處理程序被調用每次。

+0

是的,就是這一點。顯示MessageBox時,不會調用事件處理程序**。嘗試寫入控制檯,然後在處理程序中顯示消息框。 – yallie

+0

@yallie我明白你的觀點。嘗試使用'await'來序列化異步調用,如'await ThrowUnhandledException(' – clearpath

+0

)這部分代碼只是一個模擬。在我的真實應用程序中,事件異步發生(即,異步服務器調用引發異常)。 – yallie

0

我想你的程序,但它似乎工作罰款我。 ThrowUnhandledException被稱爲3次。所有三條消息都被附加到文本框中。

我嘗試添加一個MessageBox:

ThrowUnhandledException(1); 
ThrowUnhandledException(2); 
ThrowUnhandledException(3); 

MessageBox.Show("Hello"); 

但按預期工作過。我得到了消息框,但是如果我在異常處理程序上放置了一個斷點,它會被調用三次。當關閉消息框時,我可以在MyForm窗口中看到所有三條消息。

+0

沒錯,所有三條消息都會附加到文本框中。 **但在拋出異常之前會附加這些消息。** 顯示了多少個消息框? – yallie

+0

請嘗試更新的代碼示例。希望它能更清楚地表明問題。 – yallie

+0

我現在看到問題了。 – shamp00