解釋 Windows Phone 7.1 中的 NullReferenceException 或繫結參照循環錯誤

英文原文已於 2012 年 1 月 15 日星期日發佈

我最近碰到一個關於診斷與修正的棘手難題,由於我尋遍各大網站都找不到這個問題,因此,我認為我應該特地為它製作文章,以防有其他人和我一樣陷入窘境。在 Windows Phone 7.1 (亦即 Mango) 應用程式中,有一個服務參考 (在我的案例中,此為 WCF 應用程式)。WCF 應用程式會擲回一個只建立 WCF Proxy 的例外狀況,根據我的觀察,這種隨機狀況發生的次數十分頻繁。而我指的「只建立 WCF Proxy 的例外狀況」即為以下這一行的程式碼:

MyService.MyClass foo = new MyService.MyClass("myConfigSettings");

這會擲回一個例外狀況。這在本質上有些瘋狂,但是更令人費解並感到挫折的是,它每次所擲回的例外狀況不一定都一樣。它會擲回以下其中一種例外狀況,什麼時候會擲回什麼例外狀況都令人百思不得其解:

  • NullReferenceException - 這裡絕對沒有詳細資料、沒有訊息、沒有內部例外、沒有任何東西。
  • 在您的組態中偵測到繫結參照循環。您必須移除下列參考循環:basicHttpBinding/BasicHttpBinding_IMyAppInterface

關於這個問題,(許多) 蠢事中的一件蠢事就是,只有在從應用程式啟動期間所執行的特定程式碼中叫用此方法時,才會擲回例外狀況;在其他任何時間叫用該方法都不會引發任何問題。此外,如果您在解決例外狀況處理程式碼之後,向上拖曳回下一個執行以建立 Proxy 執行個體,它一定有效。另一件奇怪的事情是成功的程度不一,但最終對我有一些警告意味的是,在應用程式啟動程式碼中,有另一個執行的程式碼區塊,它也會建立該 WCF Proxy 的執行個體,而且「絕不會」失敗。因此,在嘗試找出為何有人永遠成功、有人常常失敗的原因時,查看叫用程式碼的方式即是關鍵所在。結果是,我建立了兩個不同的背景執行緒,每個背景執行緒都各執行一個不同的程式碼區塊,且都會呼叫包含程式碼的不同方法,而其包含的程式碼會建立 WCF Proxy 執行個體。因此,這證實了這的確是引發這個小問題的原因。透過重新設定程式碼,讓所有應用程式啟動工作都在單一背景執行緒上執行,就能夠神奇般地解決這個奇怪的例外狀況。

發現這個狀況當然純粹是幸運 (以及無數次的反覆試驗),因此,我認為我應該分享這個實用的程式碼,以防您也處於類似的窘境。

這是翻譯後的部落格文章。英文原文請參閱 Deciphering NullReferenceException or Binding Reference Cycle Errors in Windows Phone 7.1