如何设置可观察对象观看财产?

时间:2019-06-20 21:42:26

标签: c# system.reactive

我意识到这可能是一个非常愚蠢的问题,但是有关Reactive Extensions的文档既不透明又分散。

假设我有一堂课

public class Foo
{
    public int FooState {get;set;}
}

和FooState经常更新。对于IObservable来说,这似乎是理想的情况,尤其是因为我必须在另一个类中跟踪该状态。

public class Bar
{
    public Foo Foo {get;set;}

    private void DoStuffWithFooState()
    {
        //operate on Foo.FooState here
    }
}

现在,我无法将FooState更改为IObservable ,因为这会破坏依赖Foo的其他内容。

我想做的是在Bar上声明一个监视FooState的IObserver属性。

这不是基本用例吗?我该怎么办?

1 个答案:

答案 0 :(得分:2)

您可以使用BehaviorSubject来将属性变成可观察的流和可以从中读取最新值的属性。

public class Foo
{
    private readonly BehaviorSubject<int> _fooSubject = new BehaviorSubject<int>(0);
    public int FooState
    {
        get => _fooSubject.Value;
        set => _fooSubject.OnNext(value);
    }
    public IObservable<int> ObservableFooState => _fooSubject;
}

如果FooState的值经常变化,那么您可能需要在订阅之前使用Sample运算符。例如

//print out value every two seconds
foo.ObservableFooState
   .Sample(TimeSpan.FromSeconds(2)) 
   .Subscribe(Console.WriteLine);

请注意,常见的错误是使用Throttle,然后想知道为什么几乎没有发生任何事件! (原因是Throttle每当新事件到来时都会重置超时,因此,在流被频繁更新时,您永远都不会超过超时值。)

尽管它很旧并且部分过时,但我发现this guide在尝试了解Reactive时非常有用。 Rx HOL甚至更老,甚至已经过时,但仍然是非常有用的概念性介绍-只是不要从字面上理解代码示例。

如果此类实际上是ViewModel,则可能需要考虑ReactiveUI,但我建议您在真正熟悉Reactive之前避免使用它。

请注意,我上面没有显示“处置/完成”逻辑。您应该考虑何时(如果有)要在_fooSubject上调用OnCompleted。还请记住,subscriptions are disposable和您可能要确保在订户超出范围时将其处置。