2012-01-09 63 views
2

情況:
我有一個相當複雜的控制檯應用程序啓動多個線程,每一個生成子線程等(3個或4個級別)。一切都主要是委託/事件驅動。 我知道創建線程的範圍中的try/catch塊在開始執行時與該線程無關。我想找一個乾淨的方式來管理這個。全局異常在一個多線程叢林處理 - 故障安全/重啓

爲了說明目的,下面的模式在我的應用程序多層次經常出現:

public void Activate() 
    { 
     ThreadPool.QueueUserWorkItem(Activate_Entrypoint);  
    } 

問題:
只要我還在開發/調試,異常被拋出「對流動「在微觀層面上。
但是,我現在需要構建和準備一個生產包,因此在出現異常情況時,所有內容都需要平穩運行。所以我需要一個乾淨的用戶消息/日誌和關閉/重新啓動在頂層。

異常引發模式:
我已經實現了OnUnhandledException

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); 

然而,它似乎並沒有被提出過,因爲我期望的那樣。 錯誤編輯:它的確確實地提升了,它沒有開火,因爲我主要宣佈了綁定太遲。
我已經在不同的線程中嵌套了一個除零,我啓用/禁用來監視應用程序的行爲。

重要 - 清潔設計:
我所需要的主要頂部線只是簡單地說,其在App其餘的觀察員。 如果發生嚴重錯誤,我想這個線程以停止一切(中止已啓動的子App線程),然後再次重新啓動它。你聽過這樣的話:我不想讓一場醜陋的崩潰來阻止一切。我想在一個包裝線程中隔離應用程序,該應用程序會檢查它是否仍在運行並重新啓動它(它是一個24/7服務器端應用程序)。 我也想避免處理每一個可能的異常,這將是地獄。我只是想要一條安全帶,以便在發生未處理的異常情況時通過重新啓動應用程序從主頂線程以乾淨的方式進行處理。

可能的解決方案:
我碰到有關標誌的傳球和線程之間的定期檢查的幾個職位。這聽起來很有趣,儘管在使用大量線程級別時會變得複雜。 我正在使用Quartz.net在某些標誌上安排一個不斷的掃描任務,並採取措施使線程停止並在需要時重新啓動。尚未完成,只是給它一個鏡頭。

如果我遺漏了一些東西,請耐心等待,只是要求提供詳細信息,這不是我非常喜歡的領域(尚未)。

資源: Joseph Albahari on Threading/

+0

你需要得到AppDomain.UnhandledException的工作。很不清楚爲什麼你會遇到麻煩。 – 2012-01-09 20:44:55

+1

關於未被調用的UnhandledException,您是否嘗試過顯式拋出一個異常,而不是被零除?我並不完全確定,但我相信被零除只會導致'checked'上下文中的異常;默認情況下,編譯器將使用'unchecked'算術,因此會生成NaN或INF值而不是拋出異常。 – 2012-01-09 20:47:45

+0

可以肯定的是:只有1(一)個AppDomain有史以來? – rene 2012-01-09 20:50:41

回答

3

,你都面臨着this MSDN documentation被記錄的問題:

在線程池中的線程未處理的異常終止該進程。此規則有三個例外:

由於調用了Abort,所以在線程池線程中拋出了ThreadAbortException。

AppDomainUnloadedException在線程池線程中拋出,因爲應用程序域正在被卸載。

公共語言運行庫或主機進程終止線程。

如果在公共語言運行庫創建的線程中未處理任何這些異常,則異常終止線程,但公共語言運行時不允許異常繼續進行。

如果這些異常在主線程或從非託管代碼進入運行時的線程中未處理,它們將正常進行,從而導致應用程序終止。

根據這些信息,您將必須處理每個父線程中的異常。

我們處理一個非常類似的設計的方式是跟蹤在父級集合中啓動的每個線程。

在每次通過父進程的主循環時,我們檢查每個線程的狀態。 當線程不再活動(或在一段時間內沒有響應)時,我們知道某些事情已經過時,所以我們對子進程執行正常關閉,然後除了頂級進程之外的所有進程,我們終止線程。

然後,當主線程執行下一次通過時,它將看到子線程已經死亡並將根據需要重新啓動它們。

我們一直在使用這個相同的基礎設計運行至少10年(我們在VB6中啓動了核心),並且在許多不同的配置和負載中表現非常出色。

+0

謝謝。是'Thread.Abort()'正常關機? :) – 2012-01-09 21:13:49

+0

是的。這將引發ThreadAbortException,如果未處理,.Net將只會終止線程並且不會繼續傳播異常。 – 2012-01-09 21:18:03

+0

嗯......好吧。我會仔細看看。謝謝 – 2012-01-09 21:29:53