-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Bug][iOS] Concurrent issue leading to crash in SemaphoreSlim.Release in ObservableItemsSource #11853
Description
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.
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.