Cysharp / Cysharp/ObservableCollections
App crashes on rapid async updates when using ToNotifyCollectionChanged with WinUI 3 ListView
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 1k
- Forks
- 73
- Avg merge
- 5d 4h
- Merged PRs (30d)
- 2
Description
Description
When using ToNotifyCollectionChanged to bind an ObservableList to a WinUI 3 ListView, the application crashes with an ArgumentOutOfRangeException during rapid asynchronous updates (e.g., inside Task.Run).
Observed Behavior
- The application terminates immediately with a specific exception during collection synchronization.
- Crucially, while
CollectionChangedis subscribed to log the action, only theAddaction is ever logged before the process crashes. The subsequentRemoveaction is never reached/logged. - This crash does not occur if the same operations are performed directly on the UI thread (without
Task.Run).
Exception
System.ArgumentOutOfRangeException: This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1). (Parameter 'index')
Stack Trace
at ABI.System.Collections.IList.ToAbiHelper.EnsureIndexInt32(UInt32 index, Int32 listCapacity)
at ABI.System.Collections.IList.ToAbiHelper.GetAt(UInt32 index)
at ABI.System.Collections.IList.Do_Abi_GetAt_0(IntPtr thisPtr, UInt32 index, IntPtr* result)
--- End of stack trace from previous location ---
at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr)
at WinRT.ExceptionHelpers.ThrowExceptionForHR(Int32 hr)
at ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler.NativeDelegateWrapper.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at ObservableCollections.FiltableSynchronizedViewList`2.RaiseChangedEvent(NotifyCollectionChangedEventArgs e)
at ObservableCollections.CollectionEventDispatcherEventArgs.Invoke()
at ObservableCollections.SynchronizationContextCollectionEventDispatcher.SendOrPostCallback(Object state)
at Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.<>c__DisplayClass2_0.<Post>b__0()
Reproducible Code
<Window
x:Class="ObservableCollectionsTests.MainWindow"
xmlns="[http://schemas.microsoft.com/winfx/2006/xaml/presentation](http://schemas.microsoft.com/winfx/2006/xaml/presentation)"
xmlns:x="[http://schemas.microsoft.com/winfx/2006/xaml](http://schemas.microsoft.com/winfx/2006/xaml)">
<StackPanel>
<Button Content="Trigger Crash" Click="Button_Click"/>
<ListView ItemsSource="{x:Bind List}" />
</StackPanel>
</Window>
using Microsoft.UI.Xaml;
using ObservableCollections;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ObservableCollectionsTests;
public sealed partial class MainWindow : Window
{
private ObservableList<string> _ol = [];
public INotifyCollectionChangedSynchronizedViewList<string> List;
public MainWindow()
{
this.List = this._ol.CreateView(x => x).ToNotifyCollectionChanged(SynchronizationContextCollectionEventDispatcher.Current);
this.List.CollectionChanged += (s, e) => {
Debug.WriteLine(e.Action);
};
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
this._ol.Add("1");
this._ol.RemoveAt(0);
});
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the WinUI 3 reproduction in MainWindow with ToNotifyCollectionChanged and SynchronizationContextCollectionEventDispatcher.Current, then inspect the dispatcher and collection synchronization path implicated by the stack trace. Done means rapid background Add and RemoveAt operations no longer terminate the app and both collection-change actions can be observed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100