是否可以使用.net Rx向所有观察者发送消息?

时间:2015-06-10 14:18:31

标签: c# .net system.reactive observer-pattern

我的情况是有一个可观察的,让我们说10个观察者附在它上面。我想将消息发送给每个新的观察者,直到观察者以某种方式说可观察到它识别出消息并且它将处理它。此时此刻,我想停止向其他观察者发送此消息。

换句话说,每个观察者都知道如何处理特定类型的消息,每个消息都将采用并处理它识别的消息。其他人在识别它开始处理之后不需要接收它。如何通过反应式扩展实现这种情况?我假设我们需要某种通知回到observable,但我不知道怎么做。

1 个答案:

答案 0 :(得分:1)

这就是我想出的。任何评论,想法,建议和评论都是非常受欢迎的。最有趣的部分是IObserver<TValue, TResult>公共接口已经存在于Rx库中,但它仅在Notification对象中使用。我做了什么,我创建了IObservable<TValue, TResult>对应的SelectiveSubject来处理调用观察者的逻辑,直到其中一个返回true和ToSelective方法扩展。我真的很惊讶它没有在库中完成,至少是IObservable<TValue, TResult>部分。毕竟,IObserver<TValue, TResult>已经存在。

public interface IObservable<out TValue, in TResult> {
   IDisposable Subscribe(IObserver<TValue, TResult> objObserver);
}



internal class SelectiveSubject<T> : IObserver<T>, IObservable<T, bool> {
   private readonly LinkedList<IObserver<T, bool>> _ObserverList;

   public SelectiveSubject() {
      _ObserverList = new LinkedList<IObserver<T, bool>>();
   }

   public void OnNext(T value) {
      lock(_ObserverList) {
         foreach(IObserver<T, bool> objObserver in _ObserverList) {
            if(objObserver.OnNext(value)) {
               break;
            }
         }
      }
   }

   public void OnError(Exception exception) {
      lock(_ObserverList) {
         foreach(IObserver<T, bool> objObserver in _ObserverList) {
            if(objObserver.OnError(exception)) {
               break;
            }
         }
      }
   }

   public void OnCompleted() {
      lock(_ObserverList) {
         foreach(IObserver<T, bool> objObserver in _ObserverList) {
            if(objObserver.OnCompleted()) {
               break;
            }
         }
      }
   }

   public IDisposable Subscribe(IObserver<T, bool> objObserver) {
      LinkedListNode<IObserver<T, bool>> objNode;
      lock(_ObserverList) {
         objNode = _ObserverList.AddLast(objObserver);
      }
      return Disposable.Create(() => {
         lock(objNode.List) {
            objNode.List.Remove(objNode);
         }
      });
   }
}



public static IObservable<T, bool> ToSelective<T>(this IObservable<T> objThis) {
   var objSelective = new SelectiveSubject<T>();
   objThis.Subscribe(objSelective);
   return objSelective;
}

现在用法就像这个

一样简单
 IConnectableObservable<int> objGenerator = Observable.Generate(0, i => i < 100, i => i + 1, i => i).Publish();
 IObservable<int, bool> objSelective = objGenerator.ToSelective();

 var objDisposableList = new CompositeDisposable(2) {
    objSelective.Subscribe(i => {
       Console.Write("1");
       if(i % 2 == 0) {
          Console.Write("!");
          return true;
       }
       else {
          Console.Write(".");
          return false;
       }
    }),
    objSelective.Subscribe(i => {
       Console.Write("2");
       Console.Write("!");
       return true;
    })
 };

 objGenerator.Connect();
 objDisposableList.Dispose();

在该示例中,第一个订户处理序列中的所有其他值,第二个订户负责其余的。