WPF绑定异常



我们有一个使用Prism 6.0的WPF应用程序,它有不同的屏幕显示集合。其中许多视图在启动时加载,并在必要时显示。

偶尔,我们在启动时得到一个异常。异常调用堆栈没有提供任何有用的信息(除了它是一个跨线程集合访问问题),我们发现很难找到根本原因。例外情况如下

at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Collections.ObjectModel.Collection`1.get_Item(Int32 index)
at System.Collections.ObjectModel.ReadOnlyCollection`1.System.Collections.ICollection.CopyTo(Array array, Int32 index)
at System.Collections.ArrayList.InsertRange(Int32 index, ICollection c)
at System.Collections.ArrayList.AddRange(ICollection c)
at System.Collections.ArrayList..ctor(ICollection c)
at System.Windows.Data.ListCollectionView.<RefreshOverride>b__1_0()
at MS.Internal.Data.SynchronizationInfo.AccessCollection(IEnumerable collection, Action accessMethod, Boolean writeAccess)
at System.Windows.Data.BindingOperations.AccessCollection(IEnumerable collection, Action accessMethod, Boolean writeAccess)
at System.Windows.Data.ListCollectionView.RefreshOverride()
at System.Windows.Data.CollectionView.RefreshInternal()
at System.Windows.Data.CollectionView.RefreshOrDefer()
at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.ProcessChangeLog(ArrayList changeLog, Boolean processAll)
at System.Windows.Data.CollectionView.ProcessInvoke(Object arg)
at MS.Internal.Data.DataBindOperation.Invoke()
at MS.Internal.Data.DataBindEngine.ProcessCrossThreadRequests()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

是否有任何方法可以找出哪个集合(至少集合元素的类型)导致这个问题,或者有任何方法可以找到根本原因?

欢迎任何想法!

谢谢

该异常通常在用于访问集合的索引小于零或等于或大于集合的Count时抛出。

跨线程异常通常为NotSupportedException类型。

您必须确保索引在范围内。

要找到确切的位置,您必须转到Debug菜单并启用调试器在所有异常情况下中断,然后在调试模式下运行应用程序:

  1. Ctrl+Alt+E并勾选"公共语言运行时例外"复选框
  2. 在调试模式下运行,使程序在原始行停止(如果有适当的异常处理)

从异常消息来看,堆栈跟踪似乎是从发布版本生成的。
在这种情况下,确保您也发布了PDB文件(调试符号)。这将允许异常堆栈跟踪包含行号。

另一种选择是检查所有基于索引的集合访问(读取),并防止索引超出范围(这应该是生产代码中的标准)。您也可以利用这种机会对基于索引的写访问执行此操作。您可以使用搜索工具在您的解决方案中定位索引器。

即使包含PDB文件或使用调试模式来识别原始行,也应该考虑在搜索工具的帮助下检查代码库,以查找其他基于脆弱索引的集合访问。也许还可以在编码指南中添加一条规则,强制开发人员在通过索引访问集合之前检查集合边界。

最新更新