public DeviceService(IConnectableObservable <IDeviceView> source) { _disposable.Add(source .GroupBy(x => x.DeviceId) .Subscribe(deviceStream => { _disposable.Add(deviceStream .Scan(DeviceUpdateEvent.GetInitialView(deviceStream.Key), DeviceUtils.Update) .Subscribe(GetCreateSubject(deviceStream.Key))); })); _disposable.Add(source.Connect()); }
BehaviorSubject <DeviceUpdateEvent> GetCreateSubject(Guid deviceId) { return(_streams.GetOrAdd(deviceId, Create).Value); Lazy <BehaviorSubject <DeviceUpdateEvent> > Create(Guid id) { return(new Lazy <BehaviorSubject <DeviceUpdateEvent> >(() => { var subject = new BehaviorSubject <DeviceUpdateEvent>(DeviceUpdateEvent.GetInitialView(deviceId)); _disposable.Add(subject); return subject; })); } }
public async Task Test1() { DeviceUpdateEvent deviceView1 = null; DeviceUpdateEvent deviceView2 = null; var input = new AsyncProducerConsumerQueue <IDeviceView>(); var source = new ConnectableObservableForAsyncProducerConsumerQueue <IDeviceView>(input); var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); await input.EnqueueAsync(new DeviceVoltagesUpdateView { DeviceId = id1, Voltage = 1 }); await input.EnqueueAsync(new DeviceVoltagesUpdateView { DeviceId = id1, Voltage = 2 }); var service = new DeviceService(source); await Task.Delay(100); service.GetDeviceStream(id1).Subscribe(x => deviceView1 = x); service.GetDeviceStream(id2).Subscribe(x => deviceView2 = x); /// I believe there is no need to pause here because the Subscribe method calls above /// block until the events have all been pushed into the subscribers above. await Task.Delay(1000); Assert.AreEqual(deviceView1.View.DeviceId, id1); Assert.AreEqual(deviceView1.View.Voltage, 2); await input.EnqueueAsync(new DeviceVoltagesUpdateView { DeviceId = id2, Voltage = 100 }); await Task.Delay(1000); Assert.AreEqual(deviceView2.View.DeviceId, id2); Assert.AreEqual(deviceView2.View.Voltage, 100); //await input.EnqueueAsync(new DeviceVoltagesUpdateView { DeviceId = id2, Voltage = 101 }); //await Task.Delay(1000); /// Give the event time to propagate. //Assert.AreEqual(deviceView2.View.Voltage, 101); }