.NET: ArgumentOutOfRangeException when calling .Ad

2020-04-15 15:57发布

问题:

I'm getting an exception, but I don't understand why:

    public static void AddAll<T>(this ICollection<T> dest, ICollection<T> source)
    {
        if (dest == null)
        {
            throw new ArgumentNullException("dest");
        }

        foreach (T t in source)
        {
            // Argument out of range exception
            // Message: "\r\nParameter name: index"
            dest.Add(t);
        }
    }

The exception is:

$exception  {"\r\nParameter name: index"}   System.Exception {System.ArgumentOutOfRangeException}

Stacktrace:

   at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at System.Collections.Generic.List`1.System.Collections.IList.get_Item(Int32 index)
   at System.Windows.Controls.ItemCollection.GetItemImpl(Int32 index)
   at System.Windows.Controls.ItemCollection.GetItemImplSkipMethodPack(Int32 index)
   at System.Windows.PresentationFrameworkCollection`1.get_Item(Int32 index)
   at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.FadeInItemIfNeeded(Int32 index, Int32 visualFirstIndex, Int32 previousVisualFirstIndex, Int32 itemCount)
   at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.UpdateItemsLayout()
   at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.OnItemsChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemCollection.UpdateItemsSourceList(IEnumerable newItemsSource)
   at System.Windows.Controls.ItemsControl.ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.ItemsControl.set_ItemsSource(IEnumerable value)
   at Microsoft.Phone.Controls.Pivot.UpdateHeaders()
   at Microsoft.Phone.Controls.Pivot.OnItemsChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemCollection.System.Windows.Controls.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, SectionViewModel item)
   at System.Collections.ObjectModel.Collection`1.Add(SectionViewModel item)
   at MyApp.ExtensionMethods.AddAll[T](ICollection`1 dest, ICollection`1 source)
   at MyApp.Sections.get_SectionViewModels()
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.InternalGetValue(PropertyInfo thisProperty, Object obj, Object[] index, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at System.Windows.CLRPropertyListener.get_Value()
   at System.Windows.PropertyAccessPathStep.get_Value()
   at System.Windows.PropertyPathListener.RaisePropertyPathStepChanged(PropertyPathStep source)
   at System.Windows.PropertyAccessPathStep.RaisePropertyPathStepChanged(PropertyListener source)
   at System.Windows.CLRPropertyListener.SourcePropertyChanged(Object sender, PropertyChangedEventArgs args)
   at System.Windows.Data.WeakPropertyChangedListener.PropertyChangedCallback(Object sender, PropertyChangedEventArgs args)
   at MyApp.Sections.onPropChanged(String name)
   at MyApp.Sections.Sections_Loaded(Object sender, RoutedEventArgs e)
   at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
   at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

dest is an ObservableCollection, that currently contains t.

source is a List, that contains 7 members.

t is the first member of source.

Why could this be happening?

Update: dest is the ItemsSource for a Pivot. That Pivot is listening for dest.CollectionChanged, which I believe is causing the problem.

<controls:Pivot Title="SECTIONS" x:Name="pivotControl" ItemsSource="{Binding SectionViewModels}"> <!-- ... --> <controls:Pivot />

Here is the property that the pivot control is binding to:

        private ObservableCollection<SectionViewModel> _sectionViewModels;
        public ObservableCollection<SectionViewModel> SectionViewModels
        {
            get
            {
                // don't do anything if we haven't loaded yet
                if (NavigationContext == null)
                {
                    return null;
                }

                if (_sectionViewModels == null)
                {
                    _sectionViewModels = new ObservableCollection<SectionViewModel>();
                    _sectionViewModels.AddAll(SunData.GetSections().Select(section => new SectionViewModel(section)).ToList());

                    foreach (SectionViewModel sectionViewModel in _sectionViewModels)
                    {
                        SunData.GetStories(sectionViewModel.Section, () =>
                            {
                                onPropChanged("LoadingBarVisibility");
                            });
                    }
                }

                // re-index the source so we don't get an annoying transition animation
                // http://stackoverflow.com/questions/4541020/
                int activeVID = int.Parse(NavigationContext.QueryString[Section.SectionsKey]);

                SectionViewModel selectedItem = _sectionViewModels.Where(sectionVM => sectionVM.Section.Vid == activeVID).Single();
                int selectedIndex = _sectionViewModels.IndexOf(selectedItem);

                // one way to reindex
                for (int i = 0; i < selectedIndex; i++)
                {
                    SectionViewModel sectionVM = _sectionViewModels[0];
                    _sectionViewModels.Remove(sectionVM);
                    _sectionViewModels.Add(sectionVM);
                }

                // another way to reindex
/*
                IList<SectionViewModel> reindexedSectionVMs = new List<SectionViewModel>();
                for (int i = 0; reindexedSectionVMs.Count != _sectionViewModels.Count; i++)
                {
                    reindexedSectionVMs.Add(_sectionViewModels[(selectedIndex + i) % _sectionViewModels.Count]);
                }

                _sectionViewModels.Clear();
                _sectionViewModels.AddAll(reindexedSectionVMs);
*/
                return _sectionViewModels;
            }
        }

The key part in the code above is the re-indexing the source part. If I comment that out, I don't get this issue, nor a host of other bugs (like the content for a PivotItem being empty, or the wrong PivotItem being selected.)

I've tried two methods of reindexing the list, but they both lead to the same bugs.

I'm not sure what I'm doing here that's causing these issues.

回答1:

i found the solution to this in my problem:

Argument invalid exception while navigating



回答2:

Aha, I see it. This is not a problem with either of your 2 collections or the code you've shown above. The problem is you have something Observing these collections via change events, and there is something wrong with the event handling code there.

Hopefully, that is enough info you help you spot the problem. If not, then if you post the event handling code, we might be able to help further.