【问题标题】:How do I set an Observable to watch a Property?如何设置 Observable 来观察属性?
【发布时间】:2019-06-21 16:26:29
【问题描述】:

我意识到这可能是一个非常愚蠢的问题,但是关于 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 属性。

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

【问题讨论】:

    标签: c# system.reactive


    【解决方案1】:

    您可以使用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。

    请注意,我没有在上面显示 Dispose/Completion 逻辑。您应该考虑何时(如果有的话)要在 _fooSubject 上调用 OnCompleted。还要记住 subscriptions are disposable 并且您可能希望确保在订阅者超出范围时处理它们。

    【讨论】:

    • 谢谢!该类不是视图模型,它是由外部服务操作的对象的内存缓存的一部分。
    • 您最初的问题是有点不清楚您是否真的需要 no 对 Foo 进行更改。这能回答你的问题吗?
    • 确实如此,因为您的答案保留了 Foo 的签名。非常感谢。
    猜你喜欢
    • 2012-12-08
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    相关资源
    最近更新 更多