2009-08-20 69 views
9

在C#中合法安全地捕獲一個線程上的異常,然後將其重新扔到另一個線程上。你可以在另一個線程上重新拋出一個.NET異常嗎?

E.g.這是合法的

Exception localEx = null; 

Thread mythread = new Thread() {() => 
        { 
         try 
         { 
          DoSomeStuff(); 
         } 
         catch(Exception ex) 
         { 
          localEx = ex; 
         } 
        }); 

myThread.Start(); 
... 
myThread.Join(); 

if(localEx != null) 
    throw localEx; // rethrow on the main thread 

我認爲這是合法的,但我很難找到證明它的任何doco。我發現的最接近的是線程間異常轉移的簡短提及:http://msdn.microsoft.com/en-us/library/ms229005.aspx

+0

你可以將線程中的對象傳遞給另一個線程嗎? – Partial 2009-08-20 01:36:46

+0

@部分:當然可以。 – 2014-10-07 07:08:25

回答

11

是的,這是合法的。例外(通常來說)是沒有線程關聯性的描述性對象。

你會好起來的包裝你的線程異常在一個新的異常:

throw new Exception("Something descriptive here", localEx); 

這樣一來,在localEx堆棧跟蹤將被保留(如新的異常的InnerException)。

+1

-1:您是否打算添加引文?如果是這樣,我會樂觀的。 – 2009-08-20 01:36:26

+0

你的回答是「是的,這是合法的」。我覺得比這更需要。您已將您的答案擴展到downvote沒有必要的地步。 – 2009-08-20 01:47:54

+0

感謝您指出。我會做的。 – 2009-08-20 02:49:03

2

我不明白爲什麼它不起作用,但你需要記住,你實際上並沒有重新拋出異常。你正在拋出一個新的異常,恰好是同一個異常對象。所以,例如,堆棧跟蹤將會說它是從「throw localEx」拋出的;而不是原始異常來自哪裏。

+0

謝謝。是的,重新拋出是錯誤的詞。我將使用localEx作爲內部異常來避免您提到的調用堆棧問題。 – 2009-08-20 02:48:32

3

你在做什麼不是重演。這是您碰巧在變量中出現的異常實例的新引發。即使你只使用一個線程,這也不是個好主意,因爲它使異常看起來像是來自「throw」站點。有了多個線程,我不知道有人會發現線程發生了變化。

2

它是合法的,它不是一個重新拋出,它是在另一個線程被拋出一個新的異常(具有相同的異常對象)

0

我不知道你爲什麼認爲它不合法。如果它是非法的,編譯器會捕獲或運行時會拋出異常。事實上,我使用這種模式。 @John在使用後臺線程調用Web服務的窗體應用程序中,我使用這種方式。該異常然後在Application.ThreadException頂級處理程序中處理,記錄等等。不需要知道在哪個線程中發生了異常。

相關問題