2010-11-03 96 views
1

在某些情況下,我的.Net Windows服務可能會生成一個StackOverflowException。不幸的是,這種行爲似乎是服務停止死機,並且不會在事件日誌中寫入任何內容。我甚至沒有收到服務控制管理員發送的表示服務失敗的消息。.Net Windows服務中的StackOverflowException

有沒有辦法在所有Windows服務可以檢測已發生這樣的異常?

在此例外的文檔中,MSDN說:「請注意,承載公共語言運行庫(CLR)的應用程序可以指定CLR卸載發生堆棧溢出異常的應用程序域,並讓相應的進程繼續」。這是我期望的Windows服務實現要做的事情,但事實並非如此。

請不要只是回覆說我應該確保我的代碼永遠不會拋出這樣的異常 - 相信我,我會如果我可以 - 我想要做的是以合理的方式處理最糟糕的情況,使我的服務能夠應對意外的錯誤。

+0

您是否嘗試將調試器附加到服務? :http://msdn.microsoft.com/en-us/library/7a50syb3(VS.80).aspx嘗試找出究竟出了什麼問題? – 2010-11-03 15:26:15

+0

你是否在捕捉錯誤? – 2010-11-03 15:27:16

+0

是的,託尼,我正在盡我所能在CLR – 2010-11-03 15:37:15

回答

4

SO是一種線程可能遭受的最嚴重的心臟病。這很糟糕,你甚至沒有在事件日誌中得到什麼。這是非常糟糕的,你甚至不能做任何合理的事來恢復你的程序狀態。線程已經死亡,appdomain的狀態也是如此。它以完全不可預知的方式變異,你只能扔掉它。

那麼,你已經知道這一切。但是聳聳肩,假裝它沒有發生導致一種不同的失敗。系統故障,該服務應該做些什麼,但沒有發生。在可接受的情況下沒有太多的情況。文件沒有得到處理,數據庫更新沒有發生,等等。這種事故可能會導致一連串的事故。就像首席財務官發現在年底失去了一百萬美元。

你不想聽到這個,但沒有明智的辦法來解決這個問題。將所有的努力都集中在尋找錯誤上,而不是創可貼。而SO是總是一個編程錯誤。

+0

+1內說得好。 – 2010-11-03 15:38:32

+0

不幸的是,這種情況下的問題是由在一個100頁的用戶提供的單詞XML文檔上運行6000行XSLT轉換引起的。當然,我們將努力尋找錯誤,但是XSL的複雜性和幾乎無限範圍的輸入數據(即我們試圖處理任何word文檔),偶爾需要一個逆止機制。 – 2010-11-03 15:40:08

0

好的,一個實際的答案。你是而不是卡住了一個固定大小的堆棧。您可以使用Thread(ThreadStart,int)構造函數創建一個具有較大堆棧的構造函數。給它幾十兆字節。如果不能徹底解決問題,這應該是一個很大的方法來避免這個問題。

接下來要做的就是開始篩選您將得到處理XML文件。不太確定是否該文件的原始大小會導致.xml中的SO或錯誤的數據。首先檢查文件的大小,如果它是怪物,則將其放在單獨的目錄中。要手動處理,最好由首先創建該文件的人創建。並確保你有一些麻煩製造者文件,如果你還沒有。嘗試使用怪物線程堆棧大小離線處理它們。如果仍然存在,請開始尋找可預先篩選.xml內容的算法,以檢測問題的根源。

問另外一個問題,如果你認爲.xml文件內容的原因可能和你需要找出什麼樣的不良內容可能導致這個(不知道太多關於XLT任何東西)。

+0

感謝您增加堆棧大小的想法,我一定會放棄這一想法。目前,我設計了一個解決方案,通過該解決方案,我們可以將服務設置爲在故障時自動重新啓動,並檢測意外的進程退出並明確地失敗該任務。 不幸的是,一個單詞文檔是一件很複雜的事情(和樣式表一樣),所以很難提出一些規則來清理輸入,而不必排除某些可能工作的文檔,那樣會更糟。 – 2010-11-10 15:43:41