C# DynamicData/ReactiveUI - 将项目添加到缓存时发生意外的明确更改

C# DynamicData/ReactiveUI - Unexpected clear change when adding items to cache

我正在使用 Edit 方法对 SourceCache 进行多次更新。但是当观察结果集合的变化时,一次返回一个更新。此外,当达到 25 的更新阈值限制时,将清除并更新整个列表。虽然集合中的项目有效,但基于更改的 UI 动画并不理想。特别是在整个集合被清除并重建的情况下。以下片段重现了该问题:

样本片段:

    public class DynamicDataTest
    {
        private readonly SourceCache<string, string> _sourceCache = new SourceCache<string, string>(x => x);
        private readonly ReadOnlyObservableCollection<string> _collection;

        public DynamicDataTest()
        {
            _sourceCache.Connect()
                //.Sort(SortExpressionComparer<string>.Ascending(l => l))
                .Bind(out _collection)
                .Subscribe();

            new SourceList<string>(_collection.ToObservableChangeSet())
                .Connect()
                .ForEachChange(change => Console.WriteLine(change.Reason.ToString()))
                .Subscribe();

            _sourceCache.AddOrUpdate("start");
            _sourceCache.Edit(source =>
            {
                for (int i = 0; i < 26; i++)
                {
                    source.AddOrUpdate(i.ToString());
                }
            });
        }
    }

我希望输出:

Add or AddRange
AddRange

相反,它会导致:

AddRange
Clear
AddRange

这是预期的行为。

绑定到可观察集合时,需要进行平衡。当您有很多更改要应用时,发送重置通知通常比一次应用更改更快。重置暂停通知集合更改事件,然后清除并重新加载列表。之后它会触发重置。这就是为什么您会看到额外的清除/添加范围

这由绑定运算符中的重置阈值选项控制。例如

.Bind(out _collection, resetThreshold:100) //default=25

将在有 100 个更改要应用时触发重置,而

 .Bind(out _collection, resetThreshold:int.MaxValue)

将确保永远不会使用重置。