2014-04-30 97 views
12

我收到未處理的異常在我的應用程序,當我關閉最後一個窗口時:未處理NullReference異常關閉的WPF應用程序

型「System.NullReferenceException」 未處理的異常發生在PresentationFramework.dll

附加信息:對象引用未設置爲 對象的實例。

只有在應用程序的生命週期中,我通過已設置的特定進程打開子窗口時纔會發生這種情況。該窗口存在於另一個程序集中,該程序集在運行時用MEF動態加載,然後用Castle實例化。如果我然後調用某個方法,它會創建一個新的STA線程並打開一個WPF對話窗口。

一些注意事項:

  • 這只是發生在某些機器/環境(我不能夠辨別雖然模式)
  • 我對調度員在該應用中UnhandledException處理其捕獲所有的未處理的例外。這並沒有被抓住。

調用堆棧是:

PresentationFramework.dll!MS.Internal.Controls.ConnectionPointCookie.Disconnect() 
PresentationFramework.dll!MS.Internal.Controls.ConnectionPointCookie.Finalize() 

有沒有人見過這個,還是會有人知道如何調試呢?奇怪的是,沒有調用堆棧,並且在程序退出時發生。

+0

我認爲你需要編輯這個問題,在你的app.xaml文件中包含ShutdownMode。 –

+0

'ShutdownMode'屬性設置爲'OnMainWindowClose',但是在啓動過程中會有幾個對話框可以觸發,所以在應用程序啓動過程中它會暫時切換到'OnExplicitShutdown',但它總是**切換回**到主窗口打開之前的'OnMainWindowClose'。 – qJake

+0

我不知道是什麼導致異常,但我會嘗試通過從重定向Stderr/Stdio流的另一個應用程序中啓動它進行調試,並且希望(絕對*希望*)在這些流中存在一個可以提供線索的artefact 。 –

回答

13

您的問題缺乏細節,堆棧跟蹤很短,但提供了很多關於潛在問題的線索。一些可見的事實:

  • 終結器線程發生異常,堆棧跟蹤如此之短的原因。終結器中未處理的異常是致命的,它們總是會終止程序。試圖在代碼中使用try/catch的原因沒有效果。
  • 連接點cookie是一個COM術語,當您訂閱COM事件時會得到一個。當您取消訂閱事件時,該cookie需要再次使用,該事件發生在終結器中。在WPF中只有一個類使用它,即WebBrowser控件。 WPF類是Internet Explorer(COM組件)的一個包裝器。
  • 異常雖然具有託管異常名稱,但不是由託管代碼引起的。終結器已經檢查了空引用,它是Internet Explorer在引擎蓋下拋出一個非託管的AccessViolationException。 CLR的處理方式與CLR完全相同,因爲它們具有完全相同的原因,但終結器不會做任何其他操作來區分更清楚的事情。非託管代碼與託管代碼一樣易受空指針的影響。更重要的是,堆腐敗是一個非常普遍的原因。
  • 終結器已經捕獲所有的異常,但NRE卻是critical exception,所以它重新拋出它,這就是程序的結束。

使用WebBrowser是一個負擔,瀏覽器一般都會出現崩潰。在應用程序中使用控件時,這會被放大,它在進程中運行,並且沒有Internet Explorer自身使用的那種防撞保護。所以在瀏覽器中出現任何問題都會直接影響應用程序的穩定性,通常很難診斷崩潰原因,因爲它是非託管代碼的炸彈。

而這樣的崩潰重複得很不好,這是你自己難以得到repro的核心原因。瀏覽器中最常見的麻煩製造者是加載項,ActiveX控件(如Flash)和反惡意軟件。如果您無法控制導航的網站類型,那麼您會遇到額外的麻煩,有很多故意探測瀏覽器的漏洞。

有一種可以使用的具體對策,當你不再使用它時調用控件的Dispose()方法。通常在窗口的關閉事件處理程序中。這將立即取消註冊COM事件並觸發崩潰,現在您可以捕獲它。當發生這種情況時,強烈地考慮關閉你的程序,當你嘗試恢復它的時候,你的進程中確實有死屍,會變成殭屍。

+0

我確實使用WebBrowser控件(事實上,你能夠辨別出來,只是從堆棧跟蹤令人印象深刻),我會嘗試親自處理,看看是否能解決問題。僅供參考,該應用程序已經針對.NET 4,所以它必須像以前的版本一樣處理事情。我在測試完成後會在這裏更新。 – qJake

+0

好的,取消它,看起來好像剛剛移動了。 –

+0

看起來像是這個問題!我放置了WebBrowser並放棄了它的所有異常,並且現在應用程序關閉了。謝謝! – qJake

1

我在我的一個應用程序中遇到了同樣的問題,從未發現它背後的真正問題。但是我發現了這個應用程序的解決方法。在主窗口的關閉事件中,我實現了一個循環,以前關閉了所有其他窗口。然後它工作。也許這也適用於你。如果你發現它會更好的原因。

相關問題