2016-06-08 18 views
0

以下代碼是提高一個System.NullReferenceException:這是如何產生一個空引用異常?

 if (!App.AppIsSuspending && groupedItemsViewSource != null) 
      groupedItemsViewSource.Source = null; 

特別在Windows.UI.Xaml.Data.CollectionViewSource.put_Source(對象的值)。

我真的很難理解如何或爲什麼會發生這種情況。我對此有什麼誤解?

我想我可以把它包裝在一個嘗試...趕上,但我真的不明白爲什麼它吹了。

這是在Windows Phone上運行的WinRT應用程序,雖然我沒有足夠的遙測信息告訴我手機是否運行Windows Phone 8.1或Windows 10 Mobile。

更新:只是爲了更清楚,這個異常實際上是在CollectionViewSource.put_source中發生的。我懷疑底層代碼中存在一個錯誤,它試圖釋放先前的值,但未測試它可能爲空。這裏是實際的例外記錄:

System.NullReferenceException: Object reference not set to an instance of an object. 
    at Windows.UI.Xaml.Data.CollectionViewSource.put_Source(Object value) 
    at Relative_History.ViewEvent.<OnNavigatedFrom>d__12.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state) 
    at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore() 

我要寫一個小的演示應用程序來測試我的理論。我想刪除這個問題,因爲我可以做更多的研究,但人們已經開始回答了,所以覺得這是錯誤的。

更新:groupedItemsViewSource在XAML的頁面是提高例外聲明,即:

<Page.Resources> 
    <CollectionViewSource 
     x:Name="groupedItemsViewSource" 
     ItemsPath="GroupMembers" 
     IsSourceGrouped="True"/> 
</Page.Resources> 

然而,寫一個簡單的網頁應用程序,只是做:

groupedItemsViewSource.Source = null; 

在代碼隱藏中不會觸發相同的行爲。我已經用WP8.1和W10M仿真器測試過了。

我有點不確定爲什麼異常位也包含在異常日誌中。全OnNavigatedFrom是:

protected override async void OnNavigatedFrom(NavigationEventArgs e) 
    { 
     Debug.WriteLine("ViewEvent:OnNavigatedFrom"); 

     if (!App.AppIsSuspending && groupedItemsViewSource != null) 
      groupedItemsViewSource.Source = null; 

     if (evm != null) 
     { 
      evm.GroupBuildingCompleted -= HandleGroupBuildingCompleted; 
      await evm.CancelGroupBuilding(); 

      if (!App.AppIsSuspending) 
      { 
       evm.NoLongerInUse(); 
       evm = null; 
      } 
     } 

     navigationHelper.OnNavigatedFrom(e); 

     if (!App.AppIsSuspending) 
     { 
      this.navigationHelper.LoadState -= navigationHelper_LoadState; 
      this.navigationHelper.SaveState -= navigationHelper_SaveState; 
#if WINDOWS_APP 
      this.SizeChanged -= ViewEvent_SizeChanged; 
#endif 
     } 
    } 

,正如你所看到的,沒有任何異步代碼導致到groupedItemsViewSource.Source = NULL線。

更新:我仍然在試圖弄清楚async是如何在異常堆棧中扮演角色的。除非我誤解了事情,在Relative_History.ViewEvent.d__12.MoveNext()會暗示代碼在等待後返回?但唯一等待在OnNavigatedFrom是我設置groupedItemsViewSource.Source爲空後...

或者我誤解了異常堆棧跟蹤?

+1

調試,看看哪些變量爲空,並找出原因。 –

+1

請添加顯示System.NullReferenceException異常的重要部分。 –

回答

0

你是否將groupedItemsViewSource設置在其他地方(在不同的線程中)爲null?

主題1:

if (!App.AppIsSuspending && groupedItemsViewSource != null) 
    groupedItemsViewSource.Source = null; 

線程2:

groupedItemsViewSource = null; 

如果是這樣的: 可能發生這樣你的線程1的代碼做了檢查,那麼線程兩組變量設置爲null,之後,線程1嘗試訪問具有所見結果的源。

爲了防止出現這種情況,您可以使用.Net的鎖定機制。

在類

例如爲:

object lockGroupedItemsViewSource = new object(); 

定義鎖場,並在您訪問groupedItemsViewSource所有線程使用它。

主題1:

lock(lockGroupedItemsViewSource) 
{ 
    if (!App.AppIsSuspending && groupedItemsViewSource != null) 
     groupedItemsViewSource.Source = null; 
} 

線程2:

lock(lockGroupedItemsViewSource) 
{ 
    groupedItemsViewSource=null; 
} 

乾杯

托馬斯

+0

我做了一個代碼搜索,我沒有明確地設置groupedItemsViewSource任何地方的任何東西。它只是在XAML中定義的,我很努力地理解在OnNavigatedFrom完成執行之前頁面是如何卸載的。 –