2011-12-05 90 views
4

我試圖做到這一點引發異常:捕獲由另一種形式

我創建另一種形式,這在它的FormClosed方法拋出一個異常,應該由主要形式被捕獲。

主要形式:

try 
    { 
     frmOptions frm = new frmOptions(); 
     frm.ShowDialog();       
    } 
catch(Exception) 
    { 
     MessageBox.Show("Exception caught."); 
    } 

frmOptions:

private void frmOptions_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    throw new Exception(); 
} 

異常上的調試器停止與此消息:

例外是未處理由用戶代碼

爲什麼?我正在捕捉創建它的對象的所有者中的異常。任何人有想法?

+1

請不要把C#的稱號。這就是標籤的用途。 – Amy

+0

我不明白你描述的問題。我認爲這個問題確實存在,因爲frmOptions運行在不同的線程上,但顯然情況並非如此。我能夠發現沒有問題的例外。我測試了針對.NET 2和4. – Icarus

+0

@Icarus:轉到調試器 - >異常 - >重置全部。然後再試一次,你將通過用戶代碼得到unhnadled異常。 – mileski

回答

2

我不認爲這可以工作,新的表單不運行在上面的代碼的上下文中,它只是由它啓動。如果你檢查堆棧跟蹤拋出的異常,你不應該看到上面的代碼,所以它不能捕獲異常。

更新:我剛創建了一個測試項目&試過了。堆棧跟蹤對原始表單一無所知。如果你想趕上未處理的異常,你可能想看看這個問題Unhandled Exception Handler in .NET 1.1

+1

你是什麼意思,「它只是由它發起」?該對象是在創建它的表單的對象空間中創建的。如果我打開「不停止未處理的異常」,異常將被捕獲到主窗體的try/catch塊中。但是這也是一個「受管理」的異常處理。問題是爲什麼調試器將其視爲未固定? – mileski

+0

正如Renato在他們的回答評論中提到的那樣,新的表單在單獨的UI線程中運行,即使它是以模態方式啓動的。frmOptions中的錯誤沒有任何引用啓動窗體的堆棧跟蹤 –

+0

那麼你將得到ThreadException,而不是一個未處理的用戶代碼異常。我不相信這種情況,因爲如果關閉調試器 - 異常 - 停止未處理的用戶代碼,主窗體的try/catch塊實際上會捕獲異常。 – mileski

1

你就可以做到這一點,如下所示:

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

    private void button1_Click(object sender, EventArgs e) 
    { 
     Form2 form2 = new Form2(this); 
     form2.Show(); 
    } 

    public void HandleForm2Exception(Exception ex) 
    { 
     MessageBox.Show("EXCEPTION HAPPENED!"); 
    } 
} 

和Form2.cs

public partial class Form2 : Form 
{ 
    private Form1 form1; 

    public Form2(Form1 form1) : this() 
    { 
     this.form1 = form1; 
    } 

    public Form2() 
    { 
     InitializeComponent(); 
    } 

    private void Form2_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     try 
     { 
      throw new Exception(); 
     } 
     catch (Exception ex) 
     { 
      if(this.form1 != null) 
       this.form1.HandleForm2Exception(ex); 
     } 
    } 
} 
+0

好戲法。 +1。但是,我不推薦這種技術。 –

+0

thanx!你爲什麼不呢? – renatoargh

+0

是的,好戲,但沒有。這不是問題。請再讀一遍我的問題:) – mileski

1

你爲什麼試圖從一種形式拋出異常? "Don't throw new Exception()"

如果您試圖讓主窗體知道選項窗體已關閉,您可以在選項窗體中設置的主窗體上添加一個標誌。

+0

我知道。我在問,爲什麼調試器在異常時停止了作爲未處理的用戶代碼,實際上,在try/catch塊中創建窗體IS,並且如果您打開選項以停止調試器,則此類用戶代碼異常將被抓到最後。 – mileski

2

你可以處理所有的異常在你的項目從Program.cs中

static class Program 
     { 

      [STAThread] 
      static void Main() 
      { 
       Application.EnableVisualStyles(); 
       Application.SetCompatibleTextRenderingDefault(false); 
       AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException; 

       Application.ThreadException += Application_ThreadException; 
       Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);   
       Application.Run(new MainMDI());    
      } 
      static void Application_ThreadException(Object sender, ThreadExceptionEventArgs e) 
      { 
       MessageBox.Show(e.Exception.Message, "Application.ThreadException"); 
      } 

      static void AppDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e) 
      { 
       MessageBox.Show(((Exception)e.ExceptionObject).Message, "AppDomain.UnhandledException"); 
      } 
     } 
+0

謝謝你,但是,那不是我要問的。 – mileski