跟踪动态数据过滤器的执行和排序

问题描述 投票:0回答:1

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

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

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

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

我能够知道何时开始过滤,因为我是构建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个回答
1
投票

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

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

你能否在Github上提交一个问题,我将取消限制。

© www.soinside.com 2019 - 2024. All rights reserved.