跟踪动态数据筛选器和排序的执行情况



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

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

这个问题是,即使100000上的过滤在移动设备上发生得相对较快,用户也不知道我们是否完成了过滤。让用户知道我们正在做什么的最简单方法是在我的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($"rnSearching 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个更改,因为我刚刚运行了一个过滤器,很可能对结果感兴趣。

有人知道如何绕过这个吗?我做错什么了吗?

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

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

你能在Github上提交一个问题吗?我会取消限制。

相关内容

最新更新