question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CollectionView crashes/behaves weird when ObservableCollection updated quickly

See original GitHub issue

Description

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

  1. Clone this code: https://github.com/TheEightBot/eshop-maui-client/tree/feature/issue/collectionview-updates
  2. Run the application on iOS or macOS
  3. Login using any credentials (username: test, password: test)
  4. 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:open
  • Created a year ago
  • Reactions:2
  • Comments:14

github_iconTop GitHub Comments

3reactions
itldgcommented, Oct 16, 2022

There’s a very similar issue with CollectionView when adding and clearing items quickly that even existed on XF: xamarin/Xamarin.Forms#13268

In my own app, I have to use a bunch of Task.Delay(50) or else the collection view throws a fatal exception identical to the one linked.

Use Task Delay (50) can solve problems sometimes, thanks

2reactions
KieranMaclagancommented, Nov 24, 2022

Workaround for me was to instantiate a new ObservableCollection. Not ideal for memory usage but didn’t need hardcoded delays.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Strange Behavior of CollectionView WPF
I've got an ObservableCollection, lets call it _sourcelist. Then I create several CollectionViews of _sourcelist, in that way:
Read more >
Updating ObservableCollection in CollectionView
Hi, I am using CollectionView to display a list of ObservableCollection<BindableItems>, the objects are updated with any changes every 15 ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found