Skip to content

App crashes on rapid async updates when using ToNotifyCollectionChanged with WinUI 3 ListView #115

Description

@xm-i

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 CollectionChanged is subscribed to log the action, only the Add action is ever logged before the process crashes. The subsequent Remove action 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);
        });
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions