2010-06-01 57 views
6

如果在輔助線程中發生異常,如何在主線程中捕獲異常?如果在輔助線程中發生異常,如何在主線程中捕獲異常?

的代碼段場景下面給出:

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     Thread th1 = new Thread(new ThreadStart(Test)); 
     th1.Start();    
    } 
    catch (Exception) 
    { 

    } 
} 

void Test() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     Thread.Sleep(100); 

     if (i == 2) 
      throw new MyException(); 
    } 
} 
+0

你不能。首先,在拋出異常的時候,主線程中的try ... catch已經完成。 – 2010-06-01 05:19:49

回答

3

您可以添加一個Application.ThreadException事件處理程序:

喬是正確的。鑑於上面的Windows窗體的代碼我是假設Windows窗體:

此事件可以讓你的Windows窗體應用程序 處理,否則 Windows窗體線程發生在 未處理的異常。請附上您的 事件處理程序的ThreadException 事件處理這些異常, 將在 未知狀態離開你的應用程序。在可能的情況下, 異常應該由 結構化異常處理塊處理。

Unexpected Errors in Managed Applications

+1

我覺得這個答案是錯誤的。 AFAIK(但我沒有時間測試它),Application.ThreadException僅處理UI線程中的異常(例如,WinForms控件的事件處理程序中未處理的異常)。工作線程的異常可以由AppDomain.UnhandledException事件處理程序處理,但處理程序將在工作線程上運行,而不是在主UI線程上運行。如果要在WinForms UI線程上處理來自工作線程的異常,最好的解決方案是使用我的答案中指出的BackgroundWorker。 – Joe 2010-06-01 17:17:30

+0

可以像Windows窗體一樣容易地作爲ASP.NET代碼。它甚至可能是僞代碼。 – 2010-06-02 01:37:27

+0

是的。我目前正在開發Winforms,所以一切看起來都像winforms! – 2010-06-02 01:56:51

2

使用BackgroundWorker

一個BackgroundWorker提供了主UI線程和後臺工作線程,包括報告異常之間的通信基礎設施。它幾乎總是比從button_click事件處理程序啓動線程更好的解決方案。

+0

「??????????」 - BackgroundWorker爲主UI線程和後臺工作線程之間的通信提供基礎結構,包括報告例外。它幾乎總是一個比從OP樣本中的button_click事件處理程序啓動線程更好的解決方案。 – Joe 2010-06-01 06:43:33

+2

當然...所以把它放在你的答案:)。不是說參考文獻不好,但解釋更好! – Kiril 2010-06-01 07:22:04

0

您也可以,如果你擔心全球捕獲所有異常使用異步委託冒泡的信息。

看到here

也就是說,在陷阱線程B的例外,並使用異步代表泡信息到線程A.這樣,當從異常的數據的處理可以可以特異性地靶向。

0

正如@codeka說,你不能。但是如果你想在輔助線程的catch塊中做一些UI的東西(可能會向用戶顯示一個錯誤的MessageBox),你可以像這樣包含。如果你使用BackgroundWorker

Invoke(new Action(() => 
{ 
    MessageBox.Show("Message"); 
})); 
1

你應該考慮在您的測試方法增加您的異常處理和處理異常有其他更好的。

自由Threading in C#電子書討論這種方法(和其他一些)。向下滾動到「異常處理」部分。

0

你可以(現在&hellip;這時候沒有這個問題最初要求)使用asyncawait

private async void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     await Task.Run(Test); 
    } 
    catch (Exception) 
    { 

    } 
} 

Task.Run()方法將導致在工作線程來執行的Test()方法。如果未處理的異常是在該線程拋出,Task會傳播該異常給等待的線程在await聲明。

相關問題