Changing collection in CollectionChanged event results in exception
See original GitHub issueDescription
If you change the collection within CollectionChanged
event of an ObservableCollection
an exception is thrown: Cannot change ObservableCollection during a CollectionChanged event
.
Which at first makes sense and is probably by design to avoid ending in a loop it simply block us from making SAFE changes to the collection which dont end in a loop. Consider the following pseudo code:
var collection = new ObservableCollection<int>() { 0, 1, 2, 3, 4}
collection.CollectionChanged += (e, s) => {
if (s.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) {
collection.Move(ACollection[1], 0);
}
};
collection.Add(5);
This code is absolutely safe to execute. But an exception is thrown. The only way to get it to work is moving the modification to another thread:
var collection = new ObservableCollection<int>() { 0, 1, 2, 3, 4}
collection.CollectionChanged += (e, s) => {
if (s.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) {
Bla();
}
};
collection.Add(5);
async void Bla() {
Application.Current.Dispatcher.Invoke(() => {
collection.Move(collection[1], 0);
}, System.Windows.Threading.DispatcherPriority.Background);
}
I dont think changing it would be a breaking change because no existing code looks for and handle that specific exception. Instead of throwing an exception, a warning in VS analyzer might be better. Because an exception shouldn’t be used as a warning like it is now.
Reproduction Steps
See above
Expected behavior
No exception, at most a VS analyzer warning
Actual behavior
Exception is thrown
Regression?
No response
Known Workarounds
See above
Impact
No response
Configuration
.NET 6
Other information
No response
Issue Analytics
- State:
- Created 7 months ago
- Reactions:1
- Comments:5 (5 by maintainers)
Top GitHub Comments
I’ve created an issue in .NET runtime repo and linked it here. Closing this for now.
@Symbai I find the code of ObservableCollection is in dotnet runtime. Should you move the issue to dotnet runtime?