Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.
This repository was archived by the owner on May 1, 2024. It is now read-only.

[Bug][iOS] Concurrent issue leading to crash in SemaphoreSlim.Release in ObservableItemsSource #11853

@softlion

Description

@softlion

Description

Calls to ObservableItemsSource.BatchUpdate should be synchronized to prevent a crash in _batchUpdating.Release(), because this last one can be called 2 times in a row and will fail the second time.

https://github.com/xamarin/Xamarin.Forms/blob/main/Xamarin.Forms.Platform.iOS/CollectionView/ObservableItemsSource.cs

Steps to Reproduce

I am able to reproduce this issue easily in my customer's app.
I've already checked that all calls are done on the main thread.

It happens nearly everytime when updating the bound ObservableCollection 3 times in a row:
1st deleting some items, 2nd inserting some new items, 3rd moving some existing items (it's an algorithm that compute the changes between an ObservableCollection and a "new" list, and apply the 3 above actions so after the ObservableCollection becomes equal to the list).

I've already checked that all 3 calls are done on the main thread.

Expected Behavior

don't crash

Actual Behavior

crash when releasing the SemaphoreSlim because its CurrentCount is already 1.

Stack trace:

SemaphoreFullException: Adding the specified count to the semaphore would cause it to exceed its maximum count.

  at System.Threading.SemaphoreSlim.Release (System.Int32 releaseCount) [0x0004c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/threading/SemaphoreSlim.cs:795 
  at System.Threading.SemaphoreSlim.Release () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/threading/SemaphoreSlim.cs:760 
  at Xamarin.Forms.Platform.iOS.ObservableItemsSource.Reload () [0x00098] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:146 
  at Xamarin.Forms.Platform.iOS.ObservableItemsSource.Add (System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x00037] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:165 
  at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x00061] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:117 
  at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x000b7] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:108 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.20.2.2/src/Xamarin.iOS/Foundation/NSAction.cs:178 
--- End of stack trace from previous location where exception was thrown ---

Basic Information

  • Version with issue: 4.8
  • Last known good version: 4.5
  • IDE: VS Windows
  • Platform Target Frameworks:
    • iOS: latest stable
  • Affected Devices: iOS simulator

Screenshots

Reproduction Link

Repro app: https://github.com/softlion/ReproFormsCollectionViewBug
Run the app on an iOS simulator or device.

Tested on iOS 12.4 / iPhone 6 simulator.
But happens on all iOS OS and devices.

Does not happen on Android / UWP.

This app will trigger one of the 3 above crashes, which comes from different synchronization bugs.
The key is the change of the IsVisible property just before or after items have been added to the collectionviewsource.

Workaround

None

Other infos

I've checked the xamarin forms source code.

I'm pretty sure you can fix it easily by making BatchUpdate return a Task, then start BatchUpdate() with await _batchUpdating.WaitAsync(); instead of putting _batchUpdating.Wait() inside the PerformBatchUpdates action parameter.

Metadata

Metadata

Assignees

Labels

a/collectionviewe/5 🕔5i/highCompletely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less oftenp/iOS 🍎t/bug 🐛

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions