c#可观察到的冷热主题

时间:2019-02-06 11:21:52

标签: c# system.reactive

我经常遇到这样的情况:我希望UI元素“监视”基础值-假设我正在显示一个int-我希望我可以订阅一个IObservable。

我一直在下面使用主题,因此我可以对其进行设置。效果很好……除了第一次。如果我设置了主题-然后稍后通过打开一个新的UI元素来订阅它-它不会触发onnext直到下一次更改。

我基本上想要一种像主题一样的东西-但总是对所有新订阅者立即执行最新值的onNext。

我知道我可以自己编写这样的结构-但似乎是一个常见的用例-我缺少某些标准吗?

2 个答案:

答案 0 :(得分:1)

您需要BehaviorSubject<T>ReplaySubject<T>

BehaviorSubject<T>重播最近的单个值,并要求您在构造函数中提供一个初始值。

您可以这样使用它:

var bs = new BehaviorSubject<int>(0);
bs.Subscribe(x => Console.WriteLine(x));
bs.OnNext(42);
bs.Subscribe(x => Console.WriteLine(x));

这将向控制台输出0,然后输出42,然后42

ReplaySubject<T>有点笼统。它允许您指定要重播的值的数量,但不强制您提供初始值。

var rs = new ReplaySubject<int>(1);
rs.Subscribe(x => Console.WriteLine(x));
rs.OnNext(42);
rs.Subscribe(x => Console.WriteLine(x));

这将产生42,然后42到控制台。

将此与标准Subject<T>进行比较。

var s = new Subject<int>();
s.Subscribe(x => Console.WriteLine(x));
s.OnNext(42);
s.Subscribe(x => Console.WriteLine(x));

那只会产生42

答案 1 :(得分:-1)

如果您在UI中使用Rx,则应查看ReactiveUI

它具有方便的扩展名.ToProperty等:

_isValid = this.WhenAnyValue(x => x.Username, x => x.Password, (user, password) => !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password)).ToProperty(this, x => x.IsValid);

public bool IsValid => _isValid.Value;

这基本上就是您正在做的事情:

  • this.WhenAnyValue(x => x.Property) =>可观察的属性
  • obs.ToProperty() =>可以绑定到UI的属性可见

两者都与INotifyPropertyChanged

一起使用