2009-12-17 90 views
0

我正在處理一個WPF應用程序,它有幾個線程在後臺處理信息。如果其中一個線程崩潰,它會關閉應用程序。我將通過在try/catch中傳遞給threadstart的函數來糾正這個問題。簡單的後臺線程在.NET中重新啓動

但是,我想知道如果我能做得更好。應該可以編寫一個簡單的函數,如果失敗,它將重新啓動一個線程。甚至可以將一些規則立即嘗試重新啓動,然後延遲後續的重新啓動嘗試,這將非常簡單。基本上,它將作爲單線程的非常基本的服務控制管理器。

注意:通過「重啓」,我的意思是在新線程上再次調用該方法。

這種方法有什麼問題嗎? 在我自己寫這篇文章之前,有沒有我應該評估的現有解決方案?

我只問,因爲這似乎不是一個新問題。

+0

我想我應該注意到,在這種特殊情況下,如果我重新啓動線程,他們很可能不會再次失敗。它們主要是數據收集器,所以當它們重新啓動時,「情況」會發生變化。顯然,崩潰是應該在代碼中修復的問題,但這是針對「異常」的。 – 2009-12-17 18:07:27

回答

1

我認爲這裏有一個更根本的問題:

如果當它第一次運行時,機會是,如果你把它以同樣的方式使用相同的數據,它會拋出同樣的異常的線程拋出。重新運行剛剛失敗的完全相同的東西通常不是一個好主意。

如果異常真的是由第二次不會發生的事情引起的,那麼重試就沒有問題。然而,沒有什麼理由產生一個新線程 - 只要你的線程(在try/catch中)重試這個操作。您可以在一個簡單的循環很容易地做到這一點 - 一個天真的實現(不推薦這個,因爲它可能永遠不會結束,但它可以給你正確的想法)可能是:

bool failed = false; 
do 
{ 
    try 
    { 
     failed = false; 
     DoDangerousOperation(); 
    } 
    catch(MyException e) 
    { 
     failed = true; 
    } 
} while (failed); 

如果不是,有您應該嘗試調試一些其他問題,這很可能是由多線程引起的細微競爭條件。

0

你確實需要圍繞所有線程入口點進行try/catch以防止崩潰。這包括對Thread.Start,ThreadPool.QueueUserWorkItem,BeginInvoke,異步回調等的調用。另外,不要忘記終結器,錯誤也會導致應用程序崩潰。

至於「重新啓動」該線程,這可能是非常危險的。對所有線程進行處理意味着你不會知道已經發生了什麼,或者應用程序處於什麼狀態,並且可以將首先導致異常的任何問題複合化。除非例外是暫時的,例如網絡或基於資源,否則它也不可能成功。

針對特定類型的操作可能會暫時出錯,有針對性的重試很有用。