如何获得 IObservable 以在订阅时推送最新值 [英] How do I get an IObservable to push the newest value upon subscription

查看:24
本文介绍了如何获得 IObservable 以在订阅时推送最新值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,当您订阅某个值的更改时,您也有兴趣了解初始值.我希望我的 IObservable 缓存最新(或初始)值并将该值推送到订阅中.

Usually when you subscribe to the changes of a value you are also interested in knowing the initial value. I want my IObservable to cache the latest (or initial) value and push that value on subscription.

当使用普通事件时,我经常会得到看起来像这样的代码

When using plain events I often end up with code that looks like

x.SomeEvent += SomeEventHandler;
SomeEventHandler(x, EventArgs.Empty);

使用 IObservable 我希望用推动初始值的东西包装事件.如果我有多个订阅者,他们应该在订阅时收到最新的值如果我在创建 IObservable 后立即订阅,我有一些代码可以正常工作,但如果事件在订阅前触发则不会:

Using IObservable I was hoping to wrap the event with something that pushes the initial value. If I have multiple subscribers they should receive the newest value upon subscription I have some code that works right if I subscribe right after creating the IObservable but not if the event fires before subscribing:

class Program
{
    static void Main()
    {
        var s = new Source { Value = 1 };
        var values = Observable.Return(s.Value).Concat(
            Observable.FromEvent(
                h => s.ValueChanged += h,
                h => s.ValueChanged -= h)
            .Select(_ => s.Value));
        using (values.Subscribe(Console.WriteLine))
        {
            s.Value = 2; // prints 1,2 as expected
        }
        using (values.Subscribe(Console.WriteLine))
        {
            s.Value = 3; // prints 1,3 - expected 2,3
        }
    }
}

class Source
{
    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            if (_value == value)
                return;
            _value = value;
            if (ValueChanged != null)
                ValueChanged(this, EventArgs.Empty);
        }
    }

    public event EventHandler ValueChanged;
}

如何创建按预期工作的 IObservable?

How do I create an IObservable that works as expected?

推荐答案

解决方案是订阅一个 BehaviorSubject 到 observable,并订阅所有观察者到 BehaviorSubject.BehaviorSubject 会记住最后一个通知,并在订阅时通知新的观察者.

The solution is to subscribe a BehaviorSubject to the observable, and to subscribe all observers to the BehaviorSubject. The BehaviorSubject will remember the last notification and notify new observers of it upon subscription.

查看具有 initialValue 参数的 Observable.Publish 扩展方法.这将创建一个 IConnectableObservable,它在内部使用 BehaviorSubject.

Have a look at the Observable.Publish extension method that has a initialValue parameter. This creates an IConnectableObservable that internally uses an BehaviorSubject.

var s = new Source { Value = 1 };

var values = Observable.FromEvent(h => s.ValueChanged += h,
                                  h => s.ValueChanged -= h)
                       .Select(e => e.NewValue)
                       .Publish(s.Value);

using (values.Connect())                         // subscribes subject to event
{
    using (values.Subscribe(Console.WriteLine))  // subscribes to subject
    {
        s.Value = 2;
    }                                            // unsubscribes from subject

    using (values.Subscribe(Console.WriteLine))  // subscribes to subject
    {
        s.Value = 3;
    }                                            // unsubscribes from subject

}                                            // unsubscribes subject from event

(未经测试)

这篇关于如何获得 IObservable 以在订阅时推送最新值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆