【问题标题】:Tracking the execution of dynamic data filters and sorts跟踪动态数据过滤器和排序的执行
【发布时间】:2023-03-28 05:35:01
【问题描述】:

ReactiveUI 建议使用动态数据。我尝试迁移有意义的东西,因为我必须在我的视图模型中工作。

最近我遇到了一个我似乎无法找到解决方案的问题。在我的一个页面中,动态数据与 SourceCache 一起使用,其中包含 100,000 个项目,我需要在这些项目上应用动态过滤器和排序。

这个问题是,即使在移动设备上对 100,000 进行过滤相对较快,用户也不知道我们是否完成了过滤。让用户知道我们正在做某事的最简单方法是在我的ListView 上使用IsRefreshing

这就是问题的开始......

我能够知道过滤开始的时间,因为我是构建 Observable 触发器的人,我只是找不到可靠的方法来知道过滤何时完成强>(不总是)。

过滤器第一次运行并返回 0 个结果时会按预期工作,它只是不会在初始时间之后再次触发 0 个结果(更改),直到我们在结果中得到至少一个更改。

这意味着只要过滤器对结果集产生“更改”,我就可以显示和隐藏刷新微调器,但是一旦用户点击 0 个结果,随后的 0 个结果搜索将对结果产生 0 个更改并获胜'不触发 Observable...微调器将继续旋转,直到过滤器产生至少 1 次变化。

下面是说明问题的代码:(为简单起见,使用SourceList

var disposables = new CompositeDisposable();
var sourceList = new SourceList<string>();
ReadOnlyObservableCollection<string> results;

using (disposables)
{
    // Create 100,000 dummy strings to start with
    sourceList.Edit(
        (innerList) =>
        {
            Enumerable
                .Range(1, 100000)
                .ForEach(x => innerList.Add(x.ToString()));
        });

    // Fake text trigger to replicate WhenAnyValue
    var trigger = new Subject<string>();

    disposables.Add(trigger);

    // Dynamic filter
    var filter = trigger                    
        .Do(s =>
        {
            Console.WriteLine($"\r\nSearching for: {s}");
        })
        .Select(
            searchTerm =>
            {
                Func<string, bool> searcher = item => item.StartsWith(
                    searchTerm,
                    StringComparison.InvariantCultureIgnoreCase);

                return searcher;
            });

    disposables.Add(
        sourceList
            .Connect()
            .Filter(filter)
            .Bind(out results)
            .Subscribe(
                x =>
                {
                    Console.WriteLine($"Got {results.Count} results");
                }));

    // Those works as expected
    trigger.OnNext("99999");
    trigger.OnNext("9999");
    trigger.OnNext("9998");
    trigger.OnNext("1");
    trigger.OnNext("100001");

    // At this point, because there aren't any changes we don't get any more results
    // until we return something other than 0 items.
    trigger.OnNext("100002");
    trigger.OnNext("100003");

    // This will get results as expected.
    trigger.OnNext("99998");

}

此代码给出以下结果..注意我没有得到 100002 和 100003 的任何结果:

Searching for: 99999
Got 1 results

Searching for: 9999
Got 11 results

Searching for: 9998
Got 11 results

Searching for: 1
Got 11112 results

Searching for: 100001
Got 0 results

Searching for: 100002

Searching for: 100003

Searching for: 99998
Got 1 results

我本以为 Observable 会触发,即使它有 0 次更改,因为我刚刚运行了一个过滤器并且很可能对结果感兴趣。

有人知道如何解决这个问题吗?我做错了吗?

【问题讨论】:

    标签: c# dynamic-data reactiveui


    【解决方案1】:

    您观察到的问题是由我在动态数据早期做出的抑制空通知的历史设计决定引起的。这是出于性能原因。我正在开发一个非常繁忙的交易系统,它每秒对大型数据集进行多次动态过滤。结果被暴露为派生缓存,随后被数十个其他函数使用。抑制空结果为该系统的性能创造了奇迹。然而,这个决定很糟糕,因为它产生了严重打击你的副作用。

    一个更好的解决方案是取消该限制并允许消费者使用.NotEmpty() 运算符来选择加入。这样做可以解决您的问题。

    能否请您在 Github 上提交问题,我将取消限制。

    【讨论】:

    • 问题#206 归档。 NotEmpty() 运算符听起来是个好主意。
    猜你喜欢
    • 2012-12-15
    • 2016-10-14
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    相关资源
    最近更新 更多