2012-05-28 25 views
3

假設存在以下情況。表單上有一個按鈕,點擊後可啓動後臺工作人員。在RunWorkerCompleted事件處理程序中,有一段代碼會引發unhandeled異常。該表單從Application.Run方法開始。BackgroundWorker_RunWorkerCompleted中的TargetInvocationException

public partial class FormMain : Form 
{ 
    public FormMain() 
    { 
     InitializeComponent(); 
    } 

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     throw new Exception(); 
    } 

    private void button_Click(object sender, EventArgs e) 
    { 
     backgroundWorker.RunWorkerAsync(); 
    } 
} 

的問題是,在Application.Run調用Visual Studio的休息,而不是在FormMain.backgroundWorker_RunWorkerCompleted法「拋出新的異常()」。除了使用TargetInvocationException封裝真正的異常,並且調用堆棧減少爲Program.Main方法和導致異常的代碼因此無法檢查。

如何防止包裝?我在做一些本質上錯誤的事情嗎?

從TargetInvocationException提供的調用堆棧判斷,有很多調用方法堆積起來,對於我對消息循環的基本理解以及對線程的基本理解不夠深入。

編輯: 我知道在TargetInvocationException中存在InnerException屬性,並且可以通過查找來追蹤錯誤,但這不是問題。問題是如何在使用TargetInvocationException封裝真正的異常之前停止Visal Studio,這樣我就可以使用VS IDE提供的所有那些很好的調試功能。

+0

如果發生'TargetInvocationException''InnerException'屬性存在基礎異常。 – Damith

+0

@Damith我知道,那不是我要問的。我編輯了這個問題來防止這種答案。 –

回答

3

是的,這是使RunWorkerCompleted事件在UI線程上運行的魔法的一個不幸副作用。沒有你編寫的代碼讓它運行,所以調試器不能顯示任何相關內容,但是程序中仍然涉及的最後一個語句,即啓動消息循環的Application.Run()調用。

您必須通過強制調試器在引發異常時停止調試。 Debug + Exceptions,勾選Thrown複選框以查看CLR異常。還要注意當你在沒有調試器的情況下運行時的行爲,你會得到命運之輪對話框。使用Application.SetUnhandledExceptionMode()修復此問題。

+0

捕獲所有拋出的異常有一個令人討厭的副作用,即在每個異常中停止IDE,包括處理異常。我想仍然可以發送一個Windows消息並在主線程中的某處處理它。 –

+0

僅在特殊情況下使用例外。你已經有了一個「某處」,而你已經在主線上了。無需發送消息,在RunWorkerCompleted事件處理程序中處理它。 –

+0

事情是,我正在開發一個項目,在後臺工作完成之後必須完成一個非平凡的邏輯。如果像在字典中放置重複鍵引發異常那樣微不足道的事情,深入挖掘內部異常堆棧跟蹤是非常煩人的。別擔心我不練習「異常驅動設計」 –

相關問題