Rx .Net 根据对象 datetime 属性 触发一个动作(即日期从未来传递到过去)
Rx .Net trigger an action based on objects datetime property (ie date passes from future to past)
我对反应世界还很陌生,所以请原谅我的无知。
我有一个 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();
你想用 .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
,我们创建一个可观察对象有一个 TestObject
。 SelectMany
将其扁平化为 IObservable<TestObject>
。您可以使用 Merge
实现相同的效果。 Select(f).Merge()
大致等于 SelectMany(f)
。
关于订阅操作:我猜你 mis-read 是什么;我会建议相反。 Observables 应该有 pure-functional 代码;订阅是 side-effects 的最佳去处。
我对反应世界还很陌生,所以请原谅我的无知。
我有一个 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();
你想用 .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
,我们创建一个可观察对象有一个 TestObject
。 SelectMany
将其扁平化为 IObservable<TestObject>
。您可以使用 Merge
实现相同的效果。 Select(f).Merge()
大致等于 SelectMany(f)
。
关于订阅操作:我猜你 mis-read 是什么;我会建议相反。 Observables 应该有 pure-functional 代码;订阅是 side-effects 的最佳去处。