繁体   English   中英

为什么在RX.NET中订阅RX.NET中的observable只接受1个订阅者?

[英]Why subscribing an observable in RX.NET by Latest only accepts 1 subscriber?

我的目标是从观察者中获得两个订阅者,但我只对事件流中的最新项目感兴趣。 我希望别人被抛弃。 将此视为股票价格屏幕,每1秒更新一次并忽略任何中间值。 这是我的代码:

    var ob = Observable.Interval(TimeSpan.FromMilliseconds(100)) // fast event source
        .Latest().ToObservable().ToEvent();

    ob.OnNext += (l =>
                      {
                          Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                          Thread.Sleep(1000); // slow processing of events
                          Console.WriteLine("Latest: " + l);
                                                    });

    ob.OnNext += (l =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000); // slow processing of events
            Console.WriteLine("Latest1: " + l);
            //  subject.OnNext(l);
        });

但是由于上面的代码,尽管我附加了两个事件(即使你使用订阅符号也没关系)只定期调用第一个订阅。 第二个根本不运行。 为什么会这样 ?

首先,我认为您的要求是以下之一:

  1. 您只想获得未来的价值
  2. 或者您想获得最新值(如果有)和任何未来值
  3. 或者你只想要最新的价值(如果有的话)
  4. 或者你只想抽取刻度并获得每秒的值
  5. 或者你的消费者很慢,你需要执行减载(如在GUI中)

1)的代码

var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
    .Publish();
ob.Connect();

2)的代码

var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
    .Replay(1);
ob.Connect();    

3)的代码

var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
    .Replay(1);
ob.Connect();  
var latest = ob.Take(1); 

4)的代码可以是这样,但是你认为窗口有一些微妙的行为。

var ob = Observable.Interval(TimeSpan.FromMilliseconds(200)) // fast event source
    .Replay(1);
//Connect the hot observable
ob.Connect();

var bufferedSource = ob.Buffer(TimeSpan.FromSeconds(1))
    .Where(buffer => buffer.Any())
    .Select(buffer => buffer.Last());  

5)的代码可以在James World的博客http://www.zerobugbuild.com/?p=192上找到,并且在伦敦的许多银行应用程序中很常见。

我不认为你明白什么.Latest()的确如此。

public static IEnumerable<TSource> Latest<TSource>(
    this IObservable<TSource> source
)

可枚举序列,在每次迭代时返回最后一个采样元素,然后阻塞,直到可观察源序列中的下一个元素变为可用。

请注意,它会阻止等待来自observable的下一个元素。

因此,当您使用.Latest()IObservable<>转换为IEnumerable<>您必须使用.ToObservable()将其转换回IObservable<>以便能够调用.ToEvent() 这就是它倒下的地方。

此代码的问题在于您正在创建阻止的代码。

如果你这样做,它的工作原理:

var ob = Observable.Interval(TimeSpan.FromMilliseconds(100)).ToEvent();

没有必要调用.Latest()因为你总是从一个observable获得最新的值。 你永远无法获得更早的价值。 这是一个可观察的,而不是时间机器。

我也不明白为什么你在任何情况下调用.ToEvent() 有什么需要?

这样做:

var ob = Observable.Interval(TimeSpan.FromMilliseconds(100));

ob.Subscribe(l =>
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(1000); // slow processing of events
    Console.WriteLine("Latest: " + l);
});

ob.Subscribe(l =>
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(1000); // slow processing of events
    Console.WriteLine("Latest1: " + l);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM