多个订阅者均可观察到热点,而不会丢失任何事件

时间:2018-11-15 19:29:33

标签: c# system.reactive

我需要有一个热播报,其中包含价格供稿。这是在多个区域订阅的。

可观察对象是使用Refcount创建的,并传递给订阅。第一个订阅者订阅因此开始流并获取所有事件。第二个将错过事件,直到订阅为止,随后的订阅将执行相同的行为。

这不是事件的缺失,这是我的问题。我希望所有订阅者都获得相同的数据。也就是说,流必须仅在订阅请求完成后才开始。

有可能吗?

编辑:下面说明了两种方法及其问题。

1)

public void HotObservableSubscriptionWithRefCount()
{       
    var obs1 = Observable.Interval(TimeSpan.FromMilliseconds(500)).Select(x =>
                {
                    var publishVal = x;
                    Console.WriteLine($@"observer1 publishing {publishVal}");
                    return publishVal;
                }).Publish().RefCount();

    var obs2 = Observable.Interval(TimeSpan.FromMilliseconds(500)).Select(x =>
                {
                    var publishVal = x + 100;
                    Console.WriteLine($@"observer2 publishing {publishVal}");
                    return publishVal;
                }).Publish().RefCount();

   var sub1 = obs1.Subscribe(x => Console.WriteLine($@"subscriber1 value {x}"));
                var sub2 = obs2.Subscribe(x => Console.WriteLine($@"subscriber2 
             value {x}"));

    Thread.Sleep(TimeSpan.FromSeconds(1));

var combinedSub = obs1.Merge(obs2).Subscribe(x => Console.WriteLine($@"combined 
              subscriber value {x}"));

  Thread.Sleep(TimeSpan.FromSeconds(1));

   sub1.Dispose();
   sub2.Dispose();
   combinedSub.Dispose();

   Thread.Sleep(TimeSpan.FromSeconds(1));
}

问题:由于订阅的延迟,合并的订户缺少两个可观察值的值

2)

 public void HotObservableSubscriptionWithPublish()
{
    var obs1 = Observable.Interval(TimeSpan.FromMilliseconds(500)).Select(x =>
                {
                    var publishVal = x;
                    Console.WriteLine($@"observer1 publishing {publishVal}");
                    return publishVal;

                }).Publish();

    var obs2 = Observable.Interval(TimeSpan.FromMilliseconds(500)).Select(x =>
                {
                    var publishVal = x + 100;
                    Console.WriteLine($@"observer2 publishing {publishVal}");
                    return publishVal;
                }).Publish();

    var sub1 = obs1.Subscribe(x => Console.WriteLine($@"subscriber1 value 
               {x}"));
    var sub2 = obs2.Subscribe(x => Console.WriteLine($@"subscriber2 value 
               {x}"));

             Thread.Sleep(TimeSpan.FromSeconds(1));

    var combinedSub = obs1.Merge(obs2).Subscribe(x => 
                Console.WriteLine($@"combined subscriber value {x}"));

    obs1.Connect();
    obs2.Connect();

   Thread.Sleep(TimeSpan.FromSeconds(1));

   sub1.Dispose();
   sub2.Dispose();
   combinedSub.Dispose();

   Thread.Sleep(TimeSpan.FromSeconds(1));
}

这将确保Combinedsubsciber将获得与任何单个订户一致的值。但是,即使处置了订户,观察者仍然继续提供价值。

我需要发布者和订阅者的完整生命周期控制

1 个答案:

答案 0 :(得分:0)

Felix Keil在a comment中指出,解决方案是使用第二种方法,并通过布置两个连接来断开可连接的可观察对象。

var conn1 = obs1.Connect();
var conn2 = obs2.Connect();

/* ... */

conn2.Dispose();
conn1.Dispose();