BindableCollection races against any call which adds/removes elements before it
canton7 opened this issue · comments
Discussed in #306
Originally posted by Yoooi0 November 21, 2021
There seems to be an issue with thread safety in BindableCollection.
When two threads modify the collection at the same time, one calling ClearItems, the other calling RemoveItem, it can cause OnCollectionChanging
to throw an exception.
System.Reflection.TargetInvocationException: "An error occurred while dispatching a call to the UI Thread"
Inner Exception
ArgumentOutOfRangeException: "Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')"
at Stylet.Execute.OnUIThreadSync(Action action)
at Stylet.BindableCollection`1.RemoveItem(Int32 index)
at System.Collections.ObjectModel.Collection`1.Remove(T item)
Example timeline:
- Create BindableCollection with 1 item
- Thread 1 calls
collection.ClearItems()
- Thread 1 enters
Execute.OnUIThreadSync
- Thread 2 calls
collection.Remove(firstItem)
, this callsRemoveItem
withindex
argument set to0
- Thread 2 waits for thread 1
- Thread 1 clears the collection by calling
base.ClearItems()
- Thread 2 enters
Execute.OnUIThreadSync
- Thread 2 throws exception when calling
OnCollectionChanging
because the item at index 0 does not exist anymore