2009-08-19 44 views
6

這與previous question有關。爲什麼AppDomain異常總是會終止應用程序?

我現在想明白的是,如何防止UI線程異常終止應用程序,而非UI異常無法終止。

僅供參考,請參閱this example

最重要的是,我希望在這種情況下能夠做到的是「無聲地」終止進程 - 不顯示Windows對話框,詢問是否要發送錯誤報告。

這是我的AppDomain UnhandledExceptionHandler:

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
{    
    try 
    { 
     // Maybe do some logging here if allowed 
    } 
    catch 
    { 
    } 

    // then just terminate the application 
    Application.Exit();    
} 

UPDATE
在在this answer意見光,我想澄清的是最重要的,我想了解更多有關的機制,使UI線程能夠及早通過Application.ThreadException機制捕獲未處理的異常。並且這種行爲是否可以在非UI線程上實現。

回答

7

那麼,在谷歌做一些更多的搜索後,我發現,通過Jeff Atwood on his blog描述給予了同樣的問題,這非常有趣的解釋。

大家好, 對不起,我很困惑。這種行爲實際上是設計,儘管有時候設計會有點複雜。

要理解的第一件事是UnhandledException事件不是未處理的異常「處理程序」。 註冊事件,與文檔中所說的相反:-(,不會導致未處理的異常被處理。(從那時起它們不會被處理,但我會停止,因爲已經有了循環推理...) 的UnhandledException事件只是通知您,一個異常已經未處理,如果你想試試你的線程或應用程序死亡。FWIW之前保存的狀態,我已經建檔的錯誤,以獲得文檔固定。

只是爲了在v1.0和1版本中使事情變得複雜。1,未處理的異常並不總是意味着你的應用程序將會死亡。如果未處理的異常發生在主線程或以非託管代碼開始其生命的線程之外的其他任何地方,CLR就會發生異常並允許您的應用繼續前進。這通常是邪惡的,因爲經常發生的事情是,例如,ThreadPool線程會一個接一個地靜靜地死掉,直到你的應用程序沒有真正做任何工作。找出這種失敗的原因幾乎是不可能的。這可能是傑夫以前認爲它工作的原因......他總是在非主線程中看到崩潰。

在v2.0中,任何線程上的未處理異常都會取消應用程序。我們發現,調試崩潰比調試掛起或上述的無提示停工問題要容易得多。

順便說一下,在我的1.1機器上,來自MSDN的例子確實有預期的輸出;只是第二行直到你連接了一個調試器(或沒有)之後才顯示出來。在第2版中,我們翻轉了所有東西,這樣UnhandledException事件在調試器附着之前觸發,這似乎是大多數人所期望的。

喬納森Keljo 2月18日 CLR例外PM 喬納森Keljo,2005年下午10時02

不過,我在UI線程是如何實現讓你有一個抓的伎倆仍然有興趣 - 所有UI線程異常的所有處理程序。

更有甚者,我的方式來禁用JIT .NET調試對話框我的應用程序只(不disabling it for the whole machine as seen here

3

這並不是說任何AppDomain異常終止應用程序,它是(未處理的)任何異常將拆除AppDomain並終止應用程序。

這裏的問題是,你可以在相當高的層次上明確處理UI線程異常。但是,如果在後臺線程中有未處理的異常,則無法在同一級別輕鬆處理它,因此它往往會傳播並拉低應用程序。 Application.ThreadException允許你至少知道這是導致錯誤的原因,並且如果有必要的話記錄它。

UI線程中未處理的異常將導致相同的事情發生。

+0

@Reed很感興趣:「在UI線程中未處理的異常會導致相同發生的事情。「 - 這不是真的。請創建一個測試應用程序並自己嘗試。 – 2009-08-19 17:15:30

+1

從技術上講,我應該說「主線程未處理的異常」。 Windows窗體在UI線程上添加自己的異常處理行爲(因爲它完全在UI線程上運行),這會改變主線程的行爲。製作一個控制檯應用程序,然後嘗試一下,你會發現無論發生什麼線程事件都無關緊要 - 它們會全部拆除應用程序。 – 2009-08-19 17:20:51

+0

然後我應該重申我的問題:UI線程如何完成它的一般異常處理行爲?這是我可以複製爲非UI線程行爲的東西嗎? – 2009-08-19 17:24:15

2

這有幫助嗎?

Improved Unhandled Exception behavior in .NET 2.0

此外,該代碼似乎 「死悄悄」。你在找別的東西嗎?

using System; 

namespace UnhandledException 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; 

      throw new NotImplementedException(); 
     } 

     static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      Exception exception = (Exception)e.ExceptionObject; 
      System.Console.WriteLine("exception=[" + exception.ToString() + "]"); 

      Environment.Exit(-1); 
     } 
    } 
} 
+0

是的,當你發佈該文章時,我剛閱讀完文章和評論。 +1然而.. – 2009-08-19 17:53:44

+0

是的,Environemnt.Exit似乎在做詭計!我將把問題留出一段時間,以查看是否有人能夠深入瞭解UI線程如何完成全部例外。否則,您將對我們接受的答案進行投票! – 2009-08-19 18:07:12

+0

Application.ThreadException只是「未處理的異常處理程序」的另一種變體。有很多變體(控制檯應用程序與WinForms與WebForms與WCF等)。我不確定我瞭解你的問題。一般來說,我實施每一個適用的。 – 2009-08-19 18:18:23

相關問題