CollectionView crashes/behaves weird when ObservableCollection updated quickly
See original GitHub issueDescription
If I have a view model with an ObservableCollection<T>
bound to a CollectionView
. From the view model, I perform a Clear
and then Add
, it will crash out on iOS and macOS. On macOS, the application will sometimes not crash, but the items for the CollectionView
will not appear.
Steps to Reproduce
- Clone this code: https://github.com/TheEightBot/eshop-maui-client/tree/feature/issue/collectionview-updates
- Run the application on iOS or macOS
- Login using any credentials (username: test, password: test)
- The application will crash when trying to load the CatalogView
The crash is being triggered from code in eShopOnContainers/ViewModels/ObservableCollectionEx.cs
. There are two methods named ReloadData
which clear and reload the items of the ObservableCollection
Version with bug
Release Candidate 3 (current)
Last version that worked well
Unknown/Other
Affected platforms
iOS, macOS
Affected platform versions
macOS Monterey, iOS 15.4
Did you find any workaround?
Yes, if I handle the list updates and delay notification of changes, it will respond appropriately. Modified versions of the ReloadData
methods are provided in eShopOnContainers/ViewModels/ObservableCollectionEx.cs
that will avoid this crash.
public void ReloadData(Action<IList<T>> innerListAction)
{
Items.Clear();
innerListAction(Items);
this.OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
this.OnPropertyChanged(new PropertyChangedEventArgs("Items[]"));
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public async Task ReloadDataAsync(Func<IList<T>, Task> innerListAction)
{
Items.Clear();
await innerListAction(Items);
this.OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
this.OnPropertyChanged(new PropertyChangedEventArgs("Items[]"));
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
Relevant log output
Objective-C exception thrown. Name: System.ArgumentOutOfRangeException Reason: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') (System.ArgumentOutOfRangeException)
at System.Collections.Generic.List`1[[eShopOnContainers.Models.Catalog.CatalogItem, eShopOnContainers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].get_Item(Int32 index)
at System.Collections.ObjectModel.Collection`1[[eShopOnContainers.Models.Catalog.CatalogItem, eShopOnContainers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].System.Collections.IList.get_Item(Int32 index)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.ElementAt(Int32 index)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.get_Item(Int32 index)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.get_Item(NSIndexPath indexPath)
at Microsoft.Maui.Controls.Handlers.Items.ItemsViewController`1[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetSizeForItem(NSIndexPath indexPath)
at Microsoft.Maui.Controls.Handlers.Items.ItemsViewDelegator`2[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.ReorderableItemsViewController`1[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
at UIKit.UICollectionView.InsertItems(NSIndexPath[] indexPaths)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.<>c__DisplayClass41_0.<Add>b__0()
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.Update(Action update, NotifyCollectionChangedEventArgs args)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.Add(NotifyCollectionChangedEventArgs args)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.CollectionChanged(NotifyCollectionChangedEventArgs args)
at Microsoft.Maui.Controls.Handlers.Items.ObservableItemsSource.<>c__DisplayClass37_0.<CollectionChanged>b__0()
at Foundation.NSAsyncActionDispatcher.Apply()
Native stack trace:
0 CoreFoundation 0x00000001101bed44 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x000000011d071a65 objc_exception_throw + 48
2 libxamarin-dotnet-debug.dylib 0x000000010bc3af6f xamarin_process_managed_exception + 943
3 eShopOnContainers 0x0000000102c14d29 _ZL31native_to_managed_trampoline_10P11objc_objectP13objc_selectorPP11_MonoMethodj + 361
4 eShopOnContainers 0x0000000102c154d9 -[__MonoMac_NSAsyncActionDispatcher xamarinApplySelector] + 41
5 Foundation 0x00000001131a73bf __NSThreadPerformPerform + 179
6 CoreFoundation 0x000000011012b833 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
7 CoreFoundation 0x000000011012b72b __CFRunLoopDoSource0 + 180
8 CoreFoundation 0x000000011012abf8 __CFRunLoopDoSources0 + 242
9 CoreFoundation 0x00000001101252f4 __CFRunLoopRun + 871
10 CoreFoundation 0x0000000110124a90 CFRunLoopRunSpecific + 562
11 GraphicsServices 0x000000011fdbfc8e GSEventRunModal + 139
12 UIKitCore 0x000000012873890e -[UIApplication _run] + 928
13 UIKitCore 0x000000012873d569 UIApplicationMain + 101
14 libmonosgen-2.0.dylib 0x000000010c428b12 do_icall + 194
15 libmonosgen-2.0.dylib 0x000000010c427b2d do_icall_wrapper + 253
16 libmonosgen-2.0.dylib 0x000000010c419d4a interp_exec_method + 2970
17 libmonosgen-2.0.dylib 0x000000010c417fcf interp_runtime_invoke + 239
18 libmonosgen-2.0.dylib 0x000000010c30fc1b mono_jit_runtime_invoke + 1227
19 libmonosgen-2.0.dylib 0x000000010c232318 mono_runtime_invoke_checked + 136
20 libmonosgen-2.0.dylib 0x000000010c2390bb mono_runtime_exec_main_checked + 107
21 libmonosgen-2.0.dylib 0x000000010c3720b2 mono_jit_exec + 354
22 libxamarin-dotnet-debug.dylib 0x000000010bc4ef0d xamarin_main + 1949
23 eShopOnContainers 0x0000000102ca6954 main + 52
24 dyld 0x000000010b822f21 start_sim + 10
25 ??? 0x000000020312e51e 0x0 + 8641504542
26 ??? 0x0000000000000003 0x0 + 3
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:14
Top GitHub Comments
Use Task Delay (50) can solve problems sometimes, thanks
Workaround for me was to instantiate a new ObservableCollection. Not ideal for memory usage but didn’t need hardcoded delays.