2010-03-17 90 views
7

你怎麼能發現,一個Exception發生了Thread多線程應用程序?並連續清理資源?在.NET線程捕獲異常

因爲否則Thread可能仍然保留在內存中並正在運行。

回答

5

肖恩說,你所要做的線程方法內所有異常處理和清理,你不能做它在線程初始化中。例如:

public void Run() 
{ 
    try 
    { 
     Thread thread1 = new Thread(ThreadEntry1); 
     thread1.Start(); 

     Thread thread2 = new Thread(ThreadEntry2); 
     thread2.Start(); 
    } 
    catch (NotImplementedException) 
    { 
     // Neither are caught here 
     Console.WriteLine("Caught you"); 
    } 
} 

private void ThreadEntry1() 
{ 
    throw new NotImplementedException("Oops"); 
} 

private void ThreadEntry2() 
{ 
    throw new NotImplementedException("Oops2"); 
} 

相反,這種做法是比較獨立的,顯然也適用:

public void Run() 
{ 
    Thread thread1 = new Thread(ThreadEntry1); 
    thread1.Start(); 
} 

private void ThreadEntry1() 
{ 
    try 
    { 
     throw new NotImplementedException("Oops"); 
    } 
    catch (NotImplementedException) 
    { 
     Console.WriteLine("Ha! Caught you"); 
    } 
} 

如果你想知道,如果線程已經失敗了,那麼你應該考慮的WaitHandles數組,併發回您的呼叫方法。另一種更簡單的方法是簡單地每個線程的操作完成時間遞增計數器:

Interlocked.Increment(ref _mycounter); 
1

答:您有一個調用堆棧,你可以捕捉它的線程內和線程ID添加到我猜日誌...

如果你換你的線程在一個很好的方式,你可以添加將代碼清理到catch部分,如果需要,終止該線程。

+0

同意。我不認爲這是一個問題 - 你開始一個線程,它會進入你的一個方法......所以你不能在那裏處理異常呢? – TomTom 2010-03-17 10:27:25

2

如果你擔心這種事情,那麼你應該把你的線程入口點包裝在try/catch塊中,並且明確地進行清理。任何傳出線程入口點的異常都會導致應用程序關閉。

+0

您無法使用默認設置捕獲.Net 3.5或更低版本中的ThreadAbortException,並且您無法捕獲.Net 4.0中可能代表損壞狀態的異常,並且也使用默認設置。 所以你不能使用默認設置捕捉try catch塊的所有異常(不建議你這麼做) – 2010-03-17 12:43:02

+3

它不會拋出ThreadAbortException異常,除非你中止線程 - 也可以捕獲它們,但不能吞下它們因爲它們會自動重新升起 – 2010-03-17 12:49:24

+0

@Chris S,你說得對+1,我用吞嚥的含義來捕捉,這在政治上是不正確的。 – 2010-03-19 09:18:51

1

您可以像在任何普通函數中那樣捕獲線程中的異常。 如果一個線程你的「工作」函數被調用的DoWork然後做這樣的事情:

private void DoWork(...args...) 
{ 
try 
{ 
// Do my thread work here 
} 
catch (Exception ex) 
{ 
} 
} 
1

埃裏克利珀對在工作線程中發生異常的不良最近post。值得閱讀和理解的是,異常是「特殊的」,並且在工作線程中發生異常之後,您唯一可以確定的是,您無法再確定應用程序的狀態。