以下代码引发System.NullReferenceException:
if (!App.AppIsSuspending && groupedItemsViewSource != null)
groupedItemsViewSource.Source = null;
特别是在Windows.UI.Xaml.Data.CollectionViewSource.put_Source(Object value)中。
我真的很难理解如何或为何会发生这种情况。我对此有何误解?
我想我可以把它包起来试试......但是我真的不明白为什么会爆炸。
这是在Windows Phone上运行的WinRT应用程序,但我没有足够的遥测信息告诉我手机是否运行Windows Phone 8.1或Windows 10 Mobile。
更新:为了更清楚,异常实际上发生在CollectionViewSource.put_source中。我怀疑底层代码中有一个错误是试图释放以前的值,但是没有测试它可能为null。这是实际的异常记录:
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()
我要写一个小型的演示应用来测试我的理论。我打算删除这个问题,因为我可以做更多的研究,但人们已经开始回答了,所以觉得做错了。
更新:在XAML中为引发异常的页面声明了segmentationItemsViewSource,因此:
<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 行。
更新:我还在试图弄清楚异步是如何在异常堆栈中扮演一个角色的。除非我误解了事情,否则在Relative_History.ViewEvent.d__12.MoveNext()会建议代码在等待之后返回?但OnNavigatedFrom中唯一的等待是在我将groupsItemsViewSource.Source设置为null之后...
或者我是否误解了异常堆栈跟踪?
答案 0 :(得分:0)
你在其他地方(在不同的线程中)将groupsItemsViewSource设置为null吗?
主题1:
if (!App.AppIsSuspending && groupedItemsViewSource != null)
groupedItemsViewSource.Source = null;
主题2:
groupedItemsViewSource = null;
如果是这样的话: 可能会发生您的线程1的代码进行检查,然后线程2将变量设置为null,然后线程1尝试使用看到的结果访问源。
为防止这种情况,您可以使用.Net的锁定机制。
在班级中定义一个锁定字段
e.g:
object lockGroupedItemsViewSource = new object();
并在您访问groupedItemsViewSource的所有线程中使用它。
主题1:
lock(lockGroupedItemsViewSource)
{
if (!App.AppIsSuspending && groupedItemsViewSource != null)
groupedItemsViewSource.Source = null;
}
主题2:
lock(lockGroupedItemsViewSource)
{
groupedItemsViewSource=null;
}
干杯
托马斯