使用反应式扩展如何创建包含可能过期的值的动态列表

时间:2017-08-21 00:47:05

标签: c# system.reactive

方案

我每100毫秒收到一次不同的通知ID(Source1),我需要将每个id放在一个具有特定接收日期的Cache中,如果id来了两次我只更新日期。之后我需要搜索调用服务的ID的信息,当我在我的应用程序上收到该信息时,我需要按收到的日期显示它,每隔5秒更新一次屏幕。如果Source1在10秒范围内没有刷新任何id,则需要更改状态以将其显示在不同的类别或状态

问题

我尝试使用Reactive Extensions解决此问题,但我不确定它是否是正确的技术,因为:

  • 我不知道应该在哪里拥有缓存以及如何管理这些状态
  • 在此期间管理并发性以调用外部服务的最佳方法是什么时候我可以收到更多的ID可能是新的还是旧的

最后有一个干净的清单作为信息的结果,我可以看到哪些元素正在更新,哪些元素没有更新。

任何人都可以帮助我吗?感谢

1 个答案:

答案 0 :(得分:1)

听起来.Scan运营商可能会满足您的需求。

试试这个:

var source = new Subject<int>();

var query =
    source
        .Scan(new Dictionary<int, DateTime>(), (a, x) =>
        {
            a[x] = DateTime.Now;
            return new Dictionary<int, DateTime>(a);
        })
        .Select(x => x.OrderByDescending(y => y.Value));

您可以使用以下代码对此进行测试:

var values = new [] { 1, 2, 1, 3, 2, 1 };

Observable
    .Interval(TimeSpan.FromSeconds(5.0))
    .Take(values.Length)
    .Select(x => values[x])
    .Subscribe(source);

我明白了:

output

最好使用ImmutableDictionary,然后查询如下:

var query =
    source
        .Scan(
            new Dictionary<int, DateTime>().ToImmutableDictionary(),
            (a, x) => a.SetItem(x, DateTime.Now))
        .Select(x => x.OrderByDescending(y => y.Value));
var query =
    source
        .Scan(ImmutableDictionary<int, DateTime>.Empty, (a, x) => a.SetItem(x, DateTime.Now))
        .Select(x => Observable.Interval(TimeSpan.FromSeconds(5.0)).Select(y => x).StartWith(x))
        .Switch()
        .Select(x => x.OrderByDescending(y => y.Value));

尝试此查询 - 它会在您的信号源执行时继续生成值,但在最新值出来后每隔5秒重复最后一项(除非源生成一个值然后重置5秒计时器)。