首页 > 解决方案 > Rx .Net 触发基于对象日期时间属性的动作(即日期从未来传递到过去)

问题描述

我对反应性世界还很陌生,所以请原谅我的无知。

我有一个 Observable 对象流(如果有任何影响,则来自DynamicData缓存),我希望能够在此对象上的 DateTime 过去时触发更新此对象的操作。

因此,对于示例对象:

    class TestObject
    {
        public DateTime TriggerDate { get; set; }

        public void SomeUpdate(string avalue) => Debug.WriteLine($"{DateTime.Now:HH:mm:ss} {avalue}");
    }

我能想到的最好的就是这个,我不确定这是否是最好的方法,感觉有点乱?

        var testobjects = new List<TestObject>
        {
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(4) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(8) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(12) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(16) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(20) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(24) },
            new TestObject{ TriggerDate = DateTime.Now.AddSeconds(28) },
        }.ToObservable();

        testobjects
            .Select(x =>
            {

                // return an observable (with the one item) that I can delay and subscribe on
                var updateStatus = Observable.Return(x)
                    .Delay(x.TriggerDate - DateTime.Now) // delay until the time passes
                    .Select(test =>
                    {
                        test.SomeUpdate("hi");

                        return test;
                    })
                    .Do(
                        _ => Debug.WriteLine("onNext"),
                        ex => Debug.WriteLine($"onException {ex.Message}"),
                        () => Debug.WriteLine("onComplete"))
                    .Subscribe();

                // needed ?
                //_cleanup.Add(updateStatus);

                return x;
            })
            .Subscribe();

标签: c#system.reactive

解决方案


你想用那个.Do部分做什么?

此代码几乎等同于您所拥有的,但订阅处理有所改进。一个区别是 'onNext' 消息发生在 'Hi' 之前:

testobjects
    .SelectMany(t => Observable.Return(t)
        .Delay(t.TriggerDate)
        .Do(
            _ => Debug.WriteLine("onNext"),
            ex => Debug.WriteLine($"onException {ex.Message}"),
            () => Debug.WriteLine("onComplete")
        )
    )
    .Subscribe(t => t.SomeUpdate("Hi"));

编辑

SelectMany变平而Select没有。在这种情况下,如果您要使用Select,则进入 的类型Subscribe将是IObservable<IObservable<TestObject>>: 对于可观察对象中的每个原始TestObject对象,我们创建一个具有单个 的可观察对象TestObjectSelectMany将其展平为IObservable<TestObject>. 您可以使用Merge. Select(f).Merge()大致等于SelectMany(f)

关于订阅操作:我猜你误读了一些东西;我建议相反。Observables 应该有纯功能代码;订阅是副作用的最佳场所。


推荐阅读