使用Reactive Extensions传输模型更改

时间:2014-07-31 12:48:54

标签: system.reactive reactive-programming

我正在研究一个服务器组件,它负责在内存中缓存模型,然后将所有更改流式传输给感兴趣的客户端。

当第一个客户端请求模型(井模型密钥,每个模型都有一个用于识别它的密钥)时,将创建模型(以及对下游系统的任何订阅),然后发送到客户端,然后是更新(由下游系统生成)。任何后续客户端都应该使用更新流来获得此缓存(更新)模型。当最后一个客户端取消订阅模型时,应销毁下游订阅并销毁缓存模型。

对于Rx如何在这方面提供帮助,有没有人能指出我正确的方向。我想目前还不清楚我是如何同步状态(对象)和变化流的?我是否有两个单独的IObservable用于模型和更新?

更新:这是我到目前为止所拥有的:

        Model model = null;

        return Observable.Create((IObserver<ModelUpdate> observer) =>
        {
            model = _modelFactory.GetModel(key);
            _backendThing.Subscribe(model, observer.OnNext);
            return Disposable.Create(() =>
            {
                _backendThing.Unsubscribe(model);
            });
        })
            .Do((u) => model.MergeUpdate(u))
            .Buffer(_bufferLength)
            .Select(inp => new ModelEvent(inp))
            .Publish()
            .RefCount()
            .StartWith(new ModelEvent(model)

2 个答案:

答案 0 :(得分:0)

如果我正确理解了问题,那么Models会动态进入。在应用程序生命周期的任何时间点,模型的数量都是未知的。

为此目的,IObservable<IEnumerable<Model>>看起来像是一种方式。每次添加新模型或删除现有模型时,都会对已更新的IEnumerable<Model>进行流式处理。现在它基本上保留了旧对象,而不是每次有更新时都创建所有模型,除非有充分的理由这样做。

至于每个Model对象状态的更新,例如任何字段值或属性值的更改,我会查看Paul Betts的ReactiveUI项目,它有一个名为ReactiveObject的东西。 Reactive对象可以帮助您轻松获取更改通知,但该库主要是为WPF MVVM应用程序设计的。

以下是模型的状态更新如何与ReactiveObject一起使用

public class Model : ReactiveObject
{
  int _currentPressure;
  public int CurrentPressure
 {
   get { return _currentPressure; }
   set { this.RaiseAndSetIfChagned(ref _currentPressure, value); }
 }
}

现在,在应用程序中有Model对象的任何地方,都可以轻松获得一个Observable,它将为您提供有关对象压力分量的更新。我可以使用WhenWhenAny扩展方法。

然而,无论何时发生状态更改,您都可以不使用ReactiveUI并使用简单的IObservable。

答案 1 :(得分:0)

这样的事情可能有用,虽然你的要求对我来说并不清楚。

private static readonly ConcurrentDictionary<Key, IObservable<Model>> cache = new...

...

public IObservable<Model> GetModel(Key key)
{
   return cache.GetOrAdd(key, CreateModelWithUpdates);
}

private IObservable<Model> CreateModelWithUpdates(Key key)
{
   return Observable.Using(() => new Model(key), model => GetUpdates(model).StartWith(model))
                    .Publish((Model)null)
                    .RefCount()
                    .Where(model => model != null);
}

private IObservable<Model> GetUpdates(Model model) { ... }

...

public class Model : IDisposable
{
  ...
}