簡體   English   中英

關閉WPF應用程序時出現未處理的NullReference異常

[英]Unhandled NullReference exception when closing WPF application

當我關閉最后一個窗口時,我的應用程序中出現了未處理的異常:

PresentationFramework.dll中出現未處理的“System.NullReferenceException”類型異常

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

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

一些警告:

  • 這只發生在某些機器/環境中(雖然我無法識別模式)
  • 我在應用程序的調度程序上有一個UnhandledException處理程序,它捕獲所有未處理的異常。 這沒有被抓住。

調用堆棧是:

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

有沒有人見過這個,或者有人知道如何調試這個? 奇怪的是,沒有調用堆棧,它在程序退出時正確發生。

你的問題沒有細節,堆棧跟蹤很短,但提供了很多線索來解決潛在的問題。 一些明顯的事實:

  • 終結器線程發生異常,堆棧跟蹤如此短暫的原因。 終結器中未處理的異常是致命的,它們將始終終止程序。 嘗試在代碼中使用try / catch的原因沒有效果。
  • 連接點cookie是一個COM術語,當您訂閱COM事件時,您將得到一個。 當你取消訂閱事件時,需要再次使用該cookie,這在終結器中會發生。 WPF中只有一個類使用它,即WebBrowser控件。 WPF類是Internet Explorer的一個包裝器,它是一個COM組件。
  • 該異常雖然具有托管異常名稱,但不是由托管代碼引起的。 終結器已經檢查了空引用,它是Internet Explorer,它引發了一個非托管的AccessViolationException。 這些由CLR以完全相同的方式處理,因為它們具有完全相同的原因,終結器不會做任何事情來使區別更清楚。 非托管代碼與托管代碼一樣容易受到攻擊。 更重要的是,堆損壞是一個非常常見的原因。
  • 終結器已經捕獲了所有異常,然而NRE是一個關鍵異常,因此它重新拋出它,這就是程序的結束。

使用WebBrowser是一種負擔,瀏覽器通常容易崩潰。 當您在應用程序中使用該控件時,它會被放大,它在進程中運行,並且沒有Internet Explorer本身使用的那種崩潰保護。 因此,瀏覽器中出現問題的任何內容都會直接影響應用程序的穩定性,因為它是非常難以診斷的崩潰原因,因為它是非托管代碼。

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM